【问题标题】:How to wait during SELECT that pending INSERT commit?如何在 SELECT 期间等待挂起的 INSERT 提交?
【发布时间】:2013-07-08 08:58:33
【问题描述】:

我在 Windows 环境中使用 PostgreSQL 9.2。 我在使用 MSDTC 的 2PC (2 phase commit) 环境中。

我有一个客户端应用程序,它在 SERIALIZABLE 隔离级别启动事务,在表中为特定的外键值插入新的数据行(列上有一个索引),并投票完成交易(交易已准备好)。事务将由事务协调器提交。

紧接着,在事务之外,同一个客户端向所有行请求这个相同的特定外键值。

因为在前一个事务真正提交之前可能存在延迟,所以 SELECT 子句可能会返回数据的先前快照。事实上,它确实有时会发生,这是有问题的。当然,应用程序可能会重新设计,但在那之前,我正在寻找锁定解决方案。咨询锁?

我已经在对特定行执行 UPDATE 时解决了这个问题,然后使用 SELECT...FOR SHARE,它运行良好。 SELECT 等待事务提交并返回新旧行。

现在我正在尝试为 INSERT 解决它。 SELECT...FOR SHARE 不会立即阻塞并返回。

这里没有并发问题,因为只有一个客户端处理一组特定的行。我已经知道 MVCC。

任何帮助表示赞赏。

【问题讨论】:

  • 你试过SELECT...FOR UPDATE吗?
  • @Denis 是的,同样的结果。

标签: postgresql insert locking 2phase-commit


【解决方案1】:

要等待尚未提交的INSERT,您需要谓词锁定。 PostgreSQL 中对可序列化的支持有限的谓词锁定,但它不会直接暴露给用户。

简单的SERIALIZABLE 隔离在这里对您没有帮助,因为SERIALIZABLE 只要求有一个一个 的顺序,其中事务可能已经发生以产生一致的结果。在您的情况下,此顺序为SELECT,后跟INSERT

我能想到的唯一选择是在INSERTing 之前在桌子上加一个ACCESS EXCLUSIVE 锁。这只会在COMMIT PREPAREDROLLBACK PREPARED 时间释放,同时任何其他查询都将等待锁定。您可以通过BEFORE 触发器强制执行此操作,以避免更改应用程序的需要。但是,如果您这样做,您可能会遇到奇怪的死锁和回滚,因为INSERT 将获得较低的锁,然后您将尝试在触发器中进行锁升级。如果可能,最好在INSERT 之前运行LOCK TABLE ... IN ACCESS EXCLUSIVE MODE 命令

正如您所提到的,这主要是一个应用程序设计错误的问题。期望看到尚未提交的行并没有任何意义。

【讨论】:

  • 如果所有其他查询都将等待并且永远不会因序列化问题而失败(错误 40001),这可能会起作用。
  • @omatrot 应该是这样,但是如果您尝试使用触发器执行此操作,它们很可能会因40P01 Deadlock Detected 而失败,因为您将有两个 tx,每个 tx 都有一个低阶INSERT 的锁,每个都需要一个 ACCESS EXCLUSIVE 锁,另一个持有阻塞锁。不过,如果您一次通过多个交易INSERT,这只是一个问题。
  • 我将在 INSERT 路由之前使用 LOCK TABLE...,我可能同时有多个事务。我会及时通知你进展情况。
  • @omatrot 请记住,LOCK 直到事务COMMITs 或执行ROLLBACK 才被释放。没有手册UNLOCK。因此,如果要进行全表锁定,您将希望尽可能缩短事务并尽可能减少事务。您不会从多个工作线程中获得任何好处,因为您强制所有插入连续发生。想一想,您可以避免在SELECT 之前执行显式LOCK TABLE ... IN ACCESS EXCLUSIVE MODE 必须看到一致的数据,而不必担心在INSERTs 之前手动锁定。
  • 问题是2阶段提交不是3阶段提交。在准备+最终提交之后,资源管理器(“远程”数据库)已经与事务分离,因为它的工作已经完成。它可以参与新的(甚至是分布式的)事务。其他 RM 可以在第一个 RM 之后 提交(本地),而协调器(“事务监视器”)将总是在最后一个“提交”消息进入后完成其事务。避免这种幽灵的唯一方法是在没有中间协调器的情况下禁止访问 RM。 (来源:Gray&Reuter 10.4)
猜你喜欢
  • 2021-10-27
  • 1970-01-01
  • 1970-01-01
  • 2015-04-16
  • 2019-03-06
  • 2016-09-23
  • 1970-01-01
  • 1970-01-01
  • 2021-10-10
相关资源
最近更新 更多