PostgreSQL:如何创建最大聚合值(例如总和、计数等)限制的并发安全检查?

问题描述 投票:0回答:1

首先假设我们使用具有默认隔离级别的 PostgreSQL 16,即已提交读。 那么我们以下面的“注释”表为例:

id 文字 用户ID
1 洛雷姆_ 1
2 ipsum_ 1

假设我们要限制每个用户的所有笔记最多包含 1000 个字符。对并发环境实施此检查的正确方法是什么? 经过调查,我看到以下替代方案:

  1. 使用“可序列化”隔离级别 - 因此我们将能够在应用程序(代码)级别或数据库级别(例如使用触发器)以并发安全的方式实现此检查
  2. 使用 BEFORE / AFTER INSERT OR UPDATE 触发器 - 但如果我们使用 Read Commited 隔离级别,这种方法看起来并不安全。例如,当用户创建新笔记时,可能有其他并发事务正在进行中,该事务已经插入了新笔记(但为了防止脏读,其他操作还看不到这一点,因为事务仍在进行中)。然后事务可以简单地提交,我们将超出限制。另外据我了解,由于 PostgreSQL 使用自动提交事务隐式执行所有操作,即使我们不显式使用事务,而是使用简单的并发 INSERT / UPDATE 操作,前面描述的情况也是可能的(是真的吗? ).
  3. 在执行检查和 INSERT / UPDATE 之前,在 user 行上使用带有共享/独占锁的事务。因此,其他并发事务将等待正在运行的事务提交/回滚,并且我们将能够在应用程序(代码)级别或数据库级别(例如使用触发器)以并发安全的方式实现此检查(与列表第 1 页相同)。

我理解的一切都正确吗?有没有更好的实施替代方案?

我在列表的第 2 页中检查了我的假设,除了简单的 INSERT 查询(自动提交事务),因为我不知道如何在没有适当的负载测试的情况下检查它。

postgresql concurrency transactions rdbms
1个回答
0
投票

考虑使用可序列化隔离级别对并发 PostgreSQL 环境中的用户注释强制执行字符限制,因为它提供了出色的一致性保证。无论是在应用程序级别还是通过数据库触发器,您都可以实现此限制。作为替代方案,在检查和插入/更新注释之前利用对用户行具有共享锁或独占锁的事务是另一种安全方法。这保证了并发事务等待锁被释放。采用锁定技术时,请记住,由于更多的争用,可能会影响性能。乐观并发控制是另一种需要研究的策略;它在提交事务之前验证约束并提供较少争用的并发性。您的特殊需求将最终决定您的选择。

希望这有帮助,如果您需要更多帮助,请告诉我,我会尽力与您一起解决这个问题。

© www.soinside.com 2019 - 2024. All rights reserved.