【发布时间】:2013-06-13 16:41:21
【问题描述】:
我一定遗漏了一些关于 PostgreSQL 和 PREPARE TRANSACTION 的两阶段提交。
以下 SQL :
BEGIN; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
UPDATE person.tcities set ctyname='L ABERGEMENT CLEMENCIAT TRANSACT' WHERE ctyid = 1
提供以下锁:
4092 Private 329373 acc 15/53295 RowExclusiveLock Oui 2013-06-13 18:15:55+02 UPDATE person.tcities set ctyname='L ABERGEMENT CLEMENCIAT TRANSACT' WHERE ctyid = 1
4092 Private 329369 acc 15/53295 RowExclusiveLock Oui 2013-06-13 18:15:55+02 UPDATE person.tcities set ctyname='L ABERGEMENT CLEMENCIAT TRANSACT' WHERE ctyid = 1
4092 Private 328704 acc 15/53295 RowExclusiveLock Oui 2013-06-13 18:15:55+02 UPDATE person.tcities set ctyname='L ABERGEMENT CLEMENCIAT TRANSACT' WHERE ctyid = 1
4092 Private 327169 acc 15/53295 RowExclusiveLock Oui 2013-06-13 18:15:55+02 UPDATE person.tcities set ctyname='L ABERGEMENT CLEMENCIAT TRANSACT' WHERE ctyid = 1
4092 acc 15/53295 15/53295 ExclusiveLock Oui 2013-06-13 18:15:55+02 UPDATE person.tcities set ctyname='L ABERGEMENT CLEMENCIAT TRANSACT' WHERE ctyid = 1
4092 Private 329377 acc 15/53295 RowExclusiveLock Oui 2013-06-13 18:15:55+02 UPDATE person.tcities set ctyname='L ABERGEMENT CLEMENCIAT TRANSACT' WHERE ctyid = 1
4092 acc 15/53295 ExclusiveLock Oui 2013-06-13 18:15:55+02 UPDATE person.tcities set ctyname='L ABERGEMENT CLEMENCIAT TRANSACT' WHERE ctyid = 1
一旦交易准备好:
PREPARE TRANSACTION 'TEST'
锁不见了。
因为在 PREPARE 和 COMMIT 之间发生了小的延迟,另一个查询可能会获取旧版本的记录。
是否有配置设置来避免这种行为,还是设计使然?
提前致谢。
编辑:我在 Windows x64 上使用 PostgreSQL 9.2.2(PostgreSQL 9.2.2,由 Visual C++ build 1600 编译,64 位)
EDIT 2:以下是完整的测试用例:
在新会话中发出以下内容:
BEGIN; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
UPDATE person.tcities set ctyname='L ABERGEMENT CLEMENCIAT TRANSACT' WHERE ctyid = 1
PREPARE TRANSACTION 'TEST';
然后在另一个新会话中:
SELECT * FROM person.tcities
您将获得旧版本的记录。
【问题讨论】:
-
PostgreSQL 版本?你有没有机会使用一些旧版本?
-
@Graig-Ringer :我已经在 Windows 上更新了我的问题 => 9.2.2。
标签: postgresql transactions msdtc 2phase-commit