我一定遗漏了一些关于 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 位)
编辑 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
您将获得旧版本的记录。