PHP实战中知识总结 / PgSQL - 可重复读-Repeatable read

一、可重复读隔离级别

(1)该级别只能看到在事务开始之前被提交的数据,看不到未提交的数据或者并行事务在本事务执行期间提交的修改

(2)查询能够看见在它的事务中之前执行的更新,即使它们还没有被提交

(3)UPDATE、 DELETE、 SELECT FOR UPDATE、 SELECT FOR SHARE对于这些命令,在查询数据时的行为和 SELECT 完全一致。即只看到事务开始时已经提交的行。但在找到目标行时,这些记录可能已经被其他并发的事务阻塞,譬如更新、删除、加锁。

(4)开启此级别的事务:BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;

二、与读已提交隔离级别的区别

(1)读已提交获取的查询命令开始时已提交的数据,一个事务中前后查询到的数据可能不一致。

(2)可重复读获取的是事务开始前已提交的数据,同一个事务中前后查询获取到的数据是一致的。注意是看到的是事务中第一个非事务控制语句看到快照,而不是事务中当前语句看到的快照。

三、实例 1:验证可重复读隔离级别

1、session 1 和session 2开启事务,session 2插入数据后提交,session 1查看数据。

2、session 1 和session 2开启事务,session 2插入数据后提交,session 1尝试insert 和update session 2插入的数据。

3 session 1开启事务,本事务中插入数据后查看,结果可以看到数据,即使未提交。

结论:

(1)可重复读获取的是事务开始前已提交的数据。

(2)在该隔离级别下,查询看不到事务开始前未提交的数据,也看不到其他并发事务在该事务执行过程中提交的数据。

(3)在该隔离级别下,一个查询可以看到该事务前面未提交的数据。

四、实例2:阻塞事务回滚

结论:

第一个阻塞事务回滚后,该事务的作用将被忽略,第二个事务可以继续更新最初发现的行。

五、实例3:阻塞事务提交

1、session 1和session 2同时更新相同数据。

2、事务A修改提交后,事务B加锁。

结论:

(1)在可重复读的隔离级别中,第一个事务阻塞第二个事务,只有两个事务作用的行有交叉才会发生阻塞。

(2)第一个事务不论是修改提交或者是删除提交,被阻塞的第二个事务都不能修改、删除或者锁住第一个事务所影响的行。否则将返回 ERROR: could not serialize access due to concurrent update。

(3)第一个事务如果是仅仅锁着然后提交释放锁(select for update/share),则第二个被阻塞的事务可以进行作用最初发现的行。

PHP实战中知识总结