Read Committed隔离级别下,同一提交的更新数据会被查询读不一致吗?
这是一个理论性问题,而非实际遇到的场景。
假设存在一张Bank_Account表,结构如下:
Bank_Account ( id number, balance number )
表中初始有两行数据:
| ID | Balance |
|---|---|
| 1 | 0.00 |
| 2 | 0.00 |
有一个事务执行以下更新操作:
update Bank_Account set balance = balance + 100 where id in (1,2); commit;
由于提交操作并非瞬时完成,在该事务启动后,后续启动两个无需等待事务结束的查询语句:
select balance from Bank_Account where id = 1; select balance from Bank_Account where id = 2;
问题:是否可能返回不同结果?例如一个返回0.00,另一个返回100.00?若不可能,是什么机制阻止了这种情况?
数据库系统:任意
隔离级别:Read Committed
结论
不可能出现一个返回0.00、另一个返回100.00的情况。
核心机制解释
事务原子性:数据库事务的核心特性之一是原子性——一个事务中的所有操作要么全部成功提交,要么全部失败回滚,不存在部分提交的状态。也就是说,
update语句对两行数据的修改,只会在commit执行完成后同时生效,不会出现一行修改生效、另一行未生效的中间状态。Read Committed隔离级别的约束:在Read Committed隔离级别下,查询只能读取已经完全提交的数据。在更新事务未完成提交前,它对两行数据的修改都属于未提交的脏数据,后续查询会读取事务开始前的一致数据快照(或通过锁机制等待事务提交/回滚后再读取),因此两个查询要么都返回0.00;如果更新事务已提交完成,两个查询则都会返回100.00。
数据库一致性保障:无论是基于锁的并发控制还是多版本并发控制(MVCC),数据库都会确保在Read Committed级别下,查询不会看到事务执行过程中的中间状态。比如MVCC会为每个查询提供一个一致的数据快照,锁机制则会避免查询读取到未提交的部分修改。
内容的提问来源于stack exchange,提问作者user1508072

