2

我正在运行 PostgreSQL 9.5.3。

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

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

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

请参阅我之前发布的(过长)问题,我错误地认为我看到的行为与我正在查询的特定表有关。

我已经从krokodilko回答中修改了例程,以展示我所看到的。谢谢,鳄鱼!


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

例程 1

第 1 节:

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

第 2 节:

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

第 1 节:

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

第 2 节:

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

(为什么我在这里看到了会话 1 的效果?)

第 2 节:

testdb=# COMMIT ;
COMMIT

第 1 节:

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

第 2 节:

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

第 2 节:

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

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

第 2 节:

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

(这也是我期望看到的)

4

1 回答 1

2

根据文档(强调我的):

可重复阅读

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

我只能猜测这样做的动机,但我认为这是因为在您开始查询数据之前它并不重要。一旦你开始查询数据是一致的。

于 2017-02-19T02:02:39.197 回答