事务#1在符合第一个事务的条件(WHERE
从句)的数据集上运行,第2个事务执行一个INSERT
,并将其插入到该数据集中。如果第2个事务首先提交,那么第1个事务不应该失败吗?
我有一个如下所示的表格(在PostgreSQL 9.5 db中)
CREATE TABLE public.foo (id serial PRIMARY KEY, mynum integer);
以及以下数据
id | mynum
----+-------
1 | 10
2 | 10
3 | 10
4 | 10
(4 rows)
我同时在两个psql
控制台中运行2个串行事务:
-- both transactions
mydb=# begin;
BEGIN
mydb=# set transaction isolation level serializable;
SET
-- tx1
mydb=# select * from foo where mynum < 100;
id | mynum
----+-------
1 | 10
2 | 10
3 | 10
4 | 10
(4 rows)
--tx1: Shouldn't freeze data visible for tx1 select?
--tx2
mydb=# insert into foo (mynum) values (10);
INSERT 0 1
-- tx2 will insert next row with id 5 in foo table
-- Shouldn't insert of tx2 broke data snapshot visible for tx1?
--tx1
mydb=# update foo set mynum = 20 where id < 100;
UPDATE 4
-- Shouldn't here appear serialization fail or at least on tx1 commit?
--tx2
mydb=# commit;
COMMIT
--tx1
mydb=# commit;
COMMIT
-- tx1 Commit is OK - no any error
-- implicit tx
mydb=# select * from foo;
id | mynum
----+-------
1 | 20
2 | 20
3 | 20
4 | 20
5 | 10
(5 rows)
我想知道为什么它会这样表现,考虑到PostgreSQL文档中的说明。
引用: "为了保证真正的串行化,PostgreSQL使用谓词锁定,这意味着它保留锁定以允许确定写操作何时对与并发事务先前读取的结果产生影响,如果它先运行,则该锁定可以防止这种情况。"
链接:http://www.postgresql.org/docs/current/static/transaction-iso.html