PostgreSQL ISOLATION LEVEL生效的时间似乎是在第一次SELECT

时间:2017-02-19 01:40:20

标签: postgresql mvcc

我正在运行PostgreSQL 9.5.3。

我试图理解为什么我看到下面两个例程之间的行为有所不同。我发现这种行为违反直觉,但可能有一个很好的理由;我只是想知道它是什么。

设置ISOLATION LEVEL REPEATABLE READ似乎在第一个SELECT语句之后才生效。

两个例程之间的唯一区别是在“例程2”中我输入了多余的SELECT 1 ;语句,而在“例程1”中我没有这样做。我在“常规2”中得到了我想要的结果。

请参阅我之前发布的my (overly-lengthy) question,其中我错误地认为我所看到的行为与我正在查询的特定表格有关。

我已经从krokodilkoanswer修改了例程,以展示我所看到的内容。谢谢,krokodilko!

这些是按照列出的顺序连续执行,在两个单独的会话之间来回切换。

例程1

第1节:

testdb=# CREATE TABLE t1( x int ) ;
CREATE TABLE
testdb=# INSERT INTO t1 VALUES (1),(2),(3) ;
INSERT 0 3

第二节:

testdb=# START TRANSACTION ISOLATION LEVEL REPEATABLE READ ;
START TRANSACTION

第1节:

testdb=# DELETE FROM t1 WHERE x = 2 ;
DELETE 1

第二节:

testdb=# SELECT * FROM t1 ;
 x 
---
 1
 3
(2 rows)

(为什么我在这里看到会话1的影响?)

第二节:

testdb=# COMMIT ;
COMMIT

第1节:

testdb=# CREATE TABLE t1( x int ) ;
CREATE TABLE
testdb=# INSERT INTO t1 VALUES (1),(2),(3) ;
INSERT 0 3

第二节:

testdb=# START TRANSACTION ISOLATION LEVEL REPEATABLE READ ;
START TRANSACTION
testdb=# SELECT 1 ;
 ?column? 
----------
        1
(1 row)

(我为什么要这样做?)

第1节:

testdb=# DELETE FROM t1 WHERE x = 2 ;
DELETE 1

第二节:

testdb=# SELECT * FROM t1 ;
 x 
---
 1
 2
 3
(3 rows)

(这就是我期望看到的!)

第二节:

testdb=# COMMIT ;
COMMIT
testdb=# SELECT * FROM t1 ;
 x 
---
 1
 3
(2 rows)

(这也是我期望看到的)

1 个答案:

答案 0 :(得分:1)

根据the docs(强调我的):

  

REPEATABLE READ

     

当前事务的所有语句只能看到在此事务中执行第一个查询或数据修改语句之前提交的行。

我只能猜测以这种方式制作它的动机,但我认为这是因为在您开始查询数据之前它并不重要。一旦开始查询数据是一致的。