PHP实战中知识总结 / PgSQL - 读已提交-Read committed
一、读已提交隔离级别
(1)读已提交是PostgreSQL中的默认隔离级别。
(2)一个查询(没有FOR UPDATE/SHARE子句),只能看到查询开始之前已经被提交的数据, 而无法看到未提交的数据或在查询执行期间其它事务提交的数据。
(3)SELECT查询看到的是一个在查询开始运行前该数据库的一个快照。
(4)SELECT可以看见在它自身事务中之前执行的更新的效果,即使它们还没有被提交。
(5)在同一个事务的两个查询可能查询到的数据并不相同。可能发生不可重复读。因为其它事务可能会在第一个SELECT开始和第二个SELECT开始之间提交。
(6)UPDATE、DELETE、SELECT FOR UPDATE 和 SELECT FOR SHARE命令,在查询数据时和 SELECT 的行为一致。都是查询命令执行前已经提交的数据。这些命令在查询数据的时候,可能会被其他并发事务阻塞(如:更新操作,删除操作,或者加锁)。 阻塞事务可能会回滚或者提交。在这种情况下, 即将进行的更新将等待第一个更新事务提交或者回滚(如果它还在进行中)。 如果第一个更新事务回滚,那么它的作用将被忽略并且第二个事务可以继续更新最初发现的行。 如果第一个更新事务提交,若该行被第一个更新者删除,则第二个更新事务将忽略该行,否则第二个更新者将试图在该行的已被更新的版本上应用它的操作。
二、实例 1:验证读已提交隔离级别
结论:查询只能看到已提交的数据,未提交的数据或者查询过程中其他事务提交的数据无法看到。
二、实例2:验证可能发生不可重复读的场景
结论:在读已提交的隔离模式下,查询操作获取的结果是查询操作前已经提交的数据。因此,在同一个事务中的两次select 查询的数据可能并不相同,是可能发生不可重复读的。
三、实例3:阻塞事务回滚
1、开启两个会话,同时开启事务并更新相同数据。
2、session 1 在事务中执行回滚操作。
3、开启两个会话,同时开启事务,并更新不同的数据。
结论:
(1)第一个事务回滚,那么它的作用将被忽略,第二个事务将继续执行它的操作。
(2)两个事务更新不同的数据,不会被阻塞。
四、实例4:阻塞事务提交
1、验证删除提交
① session 1和session 2同时开启事务,session 1删除数据,session 2更新数据。
② session 1提交事务,session 2 的语句将不生。
结论:
(1)如果第一个事务进行删除提交,那么第二个事务将忽略该行。
(2)如果第一个事务影响的数据和第二个事务影响的数据不同,则不会阻塞。
2、验证更新提交
① 场景1:第一个事务更新后数据依然满足事务2的查询条件。
① 场景1:第一个事务更新后数据不满足事务2的查询条。
五、结论
(1)第一个事务提交后,如果修改后的记录仍然满足第二个事务的条件(where 子句将会重新计算来看该行被更新后的版本是否满足搜索条件),则会修改被影响。 否则将不会受影响。
(2)对于原来不满足事务B的记录,经过事务A修改满足事务B后提交的,也不会被事务B影响。事务B只作用最初发现的记录。