• 正文
    • RC(读已提交)隔离级别
    • RR(可重复读)隔离级别
  • 相关推荐
申请入驻 产业图谱

RC和RR隔离级别下SELECT操作的读取机制及差异

01/20 10:30
183
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

RC(读已提交)和 RR(可重复读)隔离级别下不同的查询语句行为不同,读取到的数据可能不同,以下是详细分析:

RC(读已提交)隔离级别

1. select * from table where id = 1 for update

读取类型:不管是否在事务中执行for update,这都是一种当前读,能确保读取的数据是最新的,因为 for update 会对符合条件的记录加排他锁。

因为RC级别下是每次执行for update都会新生成读视图,事务每次执行查询操作,都会读取最新已提交的数据,可以读到其他事务已提交的修改。

2. select * from table where id = 1:

读取类型:快照读(一致性读),基于 MVCC读视图读取的是事务开始时的快照版本。跟 for update一样,可以看到其他事务已提交的修改。

当where定位列id不是索引时,需要进行全表扫描,会涉及到回库操作。对于 for update 语句,会对全表扫描到的符合条件的记录加锁,性能较差。对于普通的 select 语句,会根据MVCC机制,根据undo log版本链读取相应的事务版本数据,虽然不加锁但由于需要扫描全表,性能也会受到影响。

RR(可重复读)隔离级别

1. select * from table where id = 1 for update

读取类型:当前读。因为for update 对符合条件的记录加锁,确保读取的数据是最新的,并且加锁。

可以读取到其他事务已提交的修改,在事务内,第一次执行完 for update后,后续的 for update 读取会看到相同的已修改结果,不会看到其他事务新的修改。因为加锁,其他事务无法修改,会阻塞或者报错。

与RR级别的区别,可以参考如下事务:

begin;select * from table where id = 1 for update;...select * from table where id = 1 for update;commit;

如果是RC级别,第一次执行for update时会对满足id = 1 的记录加锁,如果 id 是主键或唯一索引,会加行锁。当该语句执行完毕,锁会被释放,然后第二次执行for update会继续加锁,那么两次读取之间就可能读到其他事务已提交的修改内容。

而RR级别第一次执行for update时会对满足 id = 1 的记录加锁,一直到事务结束。因此RR级别事务一致性较高,而性能较低。

2. select * from table where id = 1:

读取类型:快照读(一致性读),基于事务开始时创建的快照进行读取。

只能读取到事务开始时的数据快照,不能读取到事务开始后其他事务已提交的修改,保证了在同一事务内的可重复读特性。

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录