首页新闻找找看学习计划

事务隔离级别

0
悬赏园豆:20 [已解决问题] 解决于 2019-08-05 18:01

事务可重复读的意义在哪?
根据我所理解的,不可重复读是指在一个事务中对同一数据进行多次读取时,由于其他事务对该数据进行了更新,导致事务中多次读取的结果不一致;而可重复读就是即使其他事务对该数据进行了更新,该读事务多次读取的结果也是一致的。

这样的话我就有疑惑了:数据本身就被更新了,为什么还要保证多次读取的结果一致?这也只是表面上看上去一致的呀,实际都已经改变了,相反我个人还觉得不可重复读能够及时反映数据的变化,似乎更合理一些?那么可重复读的意义在哪呢?或者说不可重复读会有什么后果呢?

Yesdito的主页 Yesdito | 初学一级 | 园豆:3
提问于:2019-08-05 14:19
< >
分享
最佳答案
0

注意:可重复读是指在“同一事务”内可重复读。假设不可重复读,那么在同一个事务内读同一个数据就会出现不一致问题,违背事务的基本要素ACID中隔离性(确保每一事务在系统中认为只有该事务在使用系统)

收获园豆:15
水墨的心 | 菜鸟二级 |园豆:361 | 2019-08-05 15:07

但是在这个事务期间,数据确确实实被别的事务更新了(并且已经提交了),那第二次还是读取原来的数据不是不能反应真实情况么?如果再拿着第二次读取的值进行计算,不是会有问题么?

Yesdito | 园豆:3 (初学一级) | 2019-08-05 15:11

看你上面提了oracle,其实要完全满足事务要求只能串行化(同一时间只执行一个事务),但是效率肯定低,所以考虑种种因素搞个折中方案,每个数据库实现者都有自己的考虑吧

水墨的心 | 园豆:361 (菜鸟二级) | 2019-08-05 15:13

@Yesdito: 是不能反应真实情况,但是事务执行本身就是一个整体。相比不能及时读和破坏这个整体后者肯定更重要吧。可重复读所读取的数据就是事务开始时刻的数据(内部永远一致,保证sql不会出现异常)

水墨的心 | 园豆:361 (菜鸟二级) | 2019-08-05 15:50

@水墨的心: 我做过实验。开启第一个事务: 第一个事务第一次读取到的数据为100.(sql1执行)
此时开启第二个事务。 将与sql1关联的数据由100修改为101,提交第二个事务。在第一个事务中再次读取,还是100,但对100(第二次读取的数据进行计算),发现是以101为基础计算的。因此不太明白这样的话,第二次读取显示101不是更反映真实情况么?

Yesdito | 园豆:3 (初学一级) | 2019-08-05 15:56

@水墨的心: 我没有明白你说的不能及时读和破坏这个整体代表的意思是什么?烦请指教

Yesdito | 园豆:3 (初学一级) | 2019-08-05 15:58

@Yesdito: 如果是MYSQL在RC和RR模式下读取数据使用的是MVCC机制(大多数情况下代替行级锁,速度快)造成的问题就是同一条数据可能会保存多份,所以读取到的数据不一定是实时数据。而且你要知道数据是不可能保证是完全实时准确的,比如刚执行完一个事务下一刻又有另一个对其修改,还不是有问题,所以与其这样,保证在一个事务内重复读取数据不混乱还是有些用的。至于你说的实验,你可以详细了解下MVCC机制。

水墨的心 | 园豆:361 (菜鸟二级) | 2019-08-05 16:45

@Yesdito: 而且我个人感觉oracle只有RC 和 Serializable两种模式说明这种东西不用太纠结,只是设计问题,要是感兴趣可以深入看下他们的实现原理。我其实也是新手,哈哈~

水墨的心 | 园豆:361 (菜鸟二级) | 2019-08-05 16:50

@水墨的心: 谢谢,可能是我想太多了,主要是这方面欠缺,就是想找个大神指点一下,哈哈

Yesdito | 园豆:3 (初学一级) | 2019-08-05 18:00
其他回答(1)
0

===========================================================================================
隔离级别 脏读(Dirty Read) 不可重复读(NonRepeatable Read) 幻读(Phantom Read)
===========================================================================================

未提交读(Read uncommitted) 可能 可能 可能

已提交读(Read committed) 不可能 可能 可能

可重复读(Repeatable read) 不可能 不可能 可能

可串行化(Serializable ) 不可能 不可能 不可能

===========================================================================================
你的提问好乱啊

收获园豆:5
Desmond | 园豆:281 (菜鸟二级) | 2019-08-05 14:56

可重复读是说同一个事务中多次读取的结果一致(比如同一个sql查询:sql1)。但如果在两次读取期间,有别的事务更改了数据(影响sql1的查询结果)并且,事务进行了提交,两次读取的结果还是一样(这是可重复读)。但实际数据库的内容已经发生了变化。这样的可重复读的意义是什么那?不要只看网上的总结(查了好久,没有说可重复读的意义在哪里)。并且oracle默认的隔离级别是已提交读(可见可重复读这个级别并不太重要)

支持(0) 反对(0) Yesdito | 园豆:3 (初学一级) | 2019-08-05 15:04

@Yesdito: 隔离级别是用来平衡数据安全性和灵活性(事务并发执行能力)。你要求的数据安全性越高,那么灵活性就越差。当然,如果你的数据库没有写操作,你选择“”未提交读“级别都没有问题。

另外,”oracle默认的隔离级别是已提交读(可见可重复读这个级别并不太重要)“,这种判断不科学。
MySQL的InnoDB引擎,默认的安全级别就是可重复读

支持(1) 反对(0) Desmond | 园豆:281 (菜鸟二级) | 2019-08-05 15:46

@Desmond: 是这样的,但我们采用一个高级别的隔离级别,一般都是为了预防影响结果显示的某个问题(或现象),如脏读等,但不可重复读好像对结果没有影响。

支持(1) 反对(0) Yesdito | 园豆:3 (初学一级) | 2019-08-05 16:01

@Yesdito: https://zh.wikipedia.org/wiki/%E4%BA%8B%E5%8B%99%E9%9A%94%E9%9B%A2#%E4%B8%8D%E5%8F%AF%E9%87%8D%E5%A4%8D%E8%AF%BB
看下”脏读“,”不可重复读“,”幻读“的例子

支持(0) 反对(0) Desmond | 园豆:281 (菜鸟二级) | 2019-08-05 22:26
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册