关于SNAPSHOT与SNAPSHOT READ COMMITTED隔离级别差异及并发机制的问询
嘿,我来帮你把这俩隔离级别掰扯明白,顺便说说READ COMMITTED怎么和快照的乐观机制搭上边儿~
核心差异:SNAPSHOT vs SNAPSHOT READ COMMITTED
首先得明确:这俩都属于基于快照的乐观并发控制范畴——你说的READ COMMITTED是悲观控制,那是传统的非快照版,而快照版的READ COMMITTED是用乐观的快照机制来实现它的语义。
SNAPSHOT隔离级别(可重复读快照版)
事务一启动,就会生成一个全局固定的快照。整个事务周期里,所有读操作都基于这个快照,完全不受其他事务提交的修改影响。
举个实际例子:你开了事务A,读某条数据是100;这时候事务B把这条数据改成200并提交;但事务A再读这条数据,还是100,直到事务A结束才会看到新值。SNAPSHOT READ COMMITTED(快照版读已提交)
这个级别下,事务里的每一次读操作都会生成新的快照,而不是用事务启动时的那个。
同样举例子:事务A第一次读数据是100;事务B改成200提交后,事务A第二次读这条数据,就会读到200了。它的核心是保证你每次读都能看到已经提交的最新数据,但同一个事务内的多次读可能看到不同状态。
快照机制如何适配READ COMMITTED的语义?
传统的READ COMMITTED是悲观的:它靠加共享锁(读完就释放)来保证只读到已提交数据,但锁竞争会带来性能损耗。而快照版的READ COMMITTED用乐观思路实现了同样的核心要求:
- 它放弃了加锁,转而用数据的版本链来记录历史状态。每次读的时候,数据库会自动找到当前时间点之前所有已提交的最新版本,生成临时快照返回数据。
- 这样既满足了READ COMMITTED的核心规则——绝不读取未提交的脏数据,又避免了悲观锁的阻塞问题,写操作和读操作可以并行,性能更好。
一句话总结适用场景
- 如果你需要事务内多次读的数据完全一致,选SNAPSHOT;
- 如果你只需要每次读都拿到最新的已提交数据,同时想避开锁竞争,选SNAPSHOT READ COMMITTED。
内容的提问来源于stack exchange,提问作者Alfin E. R.
相关产品推荐
相关产品推荐

