ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
[TOC] **读已提交隔离级别** * 读已提交是PostgreSQL中的默认隔离级别 * 一个查询(没有`FOR UPDATE/SHARE`子句),只能看到查询开始之前已经被提交的数据, 而无法看到未提交的数据或在查询执行期间其它事务提交的数据 * `SELECT`查询看到的是一个在查询开始运行前该数据库的一个快照 * `SELECT`可以看见在它自身事务中之前执行的更新的效果,即使它们还没有被提交 * 在同一个事务的两个查询可能查询到的数据并不相同。可能发生不可重复读。因为其它事务可能会在第一个`SELECT`开始和第二个`SELECT`开始之间提交 * UPDATE、DELETE、SELECT FOR UPDATE 和 SELECT FOR SHARE命令,在查询数据时和 SELECT 的行为一致。都是查询命令执行前已经提交的数据。这些命令在查询数据的时候,可能会被其他并发事务阻塞(如:更新操作,删除操作,或者加锁)。 阻塞事务可能会回滚或者提交。在这种情况下, 即将进行的更新将等待第一个更新事务提交或者回滚(如果它还在进行中)。 如果第一个更新事务回滚,那么它的作用将被忽略并且第二个事务可以继续更新最初发现的行。 如果第一个更新事务提交,若该行被第一个更新者删除,则第二个更新事务将忽略该行,否则第二个更新者将试图在该行的已被更新的版本上应用它的操作 <br> # <span style="font-size:15px">**实例 1:验证读已提交隔离级别**</span> ![](https://img.kancloud.cn/a1/d5/a1d514e2ce2be1c983c30b1d6dd58b40_1522x407.png) **结论:** &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;查询只能看到已提交的数据,未提交的数据或者查询过程中其他事务提交的数据无法看到 <br> # <span style="font-size:15px">**实例2:验证可能发生不可重复读的场景**</span> ![](https://img.kancloud.cn/89/a2/89a221dfa31f8a6a6bd4d1f143235313_1527x371.png) **结论:** &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在读已提交的隔离模式下,查询操作获取的结果是查询操作前已经提交的数据。因此,在同一个事务中的两次select 查询的数据可能并不相同,是可能发生不可重复读的。 <br> # <span style="font-size:15px">**实例3:阻塞事务回滚**</span> 1. 开启两个会话,同时开启事务并更新相同数据 ![](https://img.kancloud.cn/be/de/bede9397cf15383f0b108bf30edf18f0_1606x278.png) 2. session 1 在事务中执行回滚操作 ![](https://img.kancloud.cn/93/9d/939dca32268cffb9553903d5de4bd1c1_1442x311.png) 3. 开启两个会话,同时开启事务,并更新不同的数据 ![](https://img.kancloud.cn/8a/e7/8ae7c14d3d6805e0b5e05944c394921a_1524x230.png) **结论:** * 第一个事务回滚,那么它的作用将被忽略,第二个事务将继续执行它的操作 * 两个事务更新不同的数据,不会被阻塞 <br> # <span style="font-size:15px">**实例4:阻塞事务提交**</span> 1. 验证删除提交 ① session 1和session 2同时开启事务,session 1删除数据,session 2更新数据 ![](https://img.kancloud.cn/cf/9f/cf9f53b7987016a7ed0c5c8c612936c7_1554x382.png) ② session 1提交事务,session 2 的语句将不生效 ![](https://img.kancloud.cn/54/a7/54a712a303d75fc247bb5426e44d56ab_1538x487.png) **结论:** * 如果第一个事务进行删除提交,那么第二个事务将忽略该行。 * 如果第一个事务影响的数据和第二个事务影响的数据不同,则不会阻塞。 2. 验证更新提交 ① 场景1:第一个事务更新后数据依然满足事务2的查询条件 ![](https://img.kancloud.cn/92/42/9242e948f5f0b9dded02d0a77931eb8a_1634x371.png) ![](https://img.kancloud.cn/7b/94/7b947cb04a050118782b1523bcb72abe_1531x344.png) ① 场景1:第一个事务更新后数据不满足事务2的查询条件 ![](https://img.kancloud.cn/ea/60/ea6057a3ad2c0d92261110940ea94acb_1571x261.png) **结论:** * 第一个事务提交后,如果修改后的记录仍然满足第二个事务的条件(where 子句将会重新计算来看该行被更新后的版本是否满足搜索条件),则会修改被影响。 否则将不会受影响。 * 对于原来不满足事务B的记录,经过事务A修改满足事务B后提交的,也不会被事务B影响。事务B只作用最初发现的记录