文章目录

前言

最近在看《Servlet/JSP深入详解》,毕竟马上要做这方面的工作了,得复习一下。又看到了事务处理的问题,把以前上数据库课的一些有意思的问题又回忆了起来,记录一下。

有关脏读

脏读是最简单的一种冲突类型。

【定义】A事务访问并修改了数据,但未提交;B事务读取了A事务修改后的数据,发生了脏读。

【隐患】若A回滚,则B所做的一切操作都是错的。

【举例】对同一账户的存取款,A为取款事务,B为转账事务,操作时间片如表所示。

时间片 取款事务A 转账事务B 
 T1 START 
 T2  START
 T3 查询余额为1000元 
 T4 准备取走300元,修改余额为700元 
 T5  查询余额为700元
 T6 机器没钱了,ROLLBACK,恢复余额为1000元 
 T7  汇入100元,修改余额为600元
 T8  COMMIT

预期结果:1000+100=1100元

实际结果:600元

问题出在T5时刻B发生了脏读。

有关不可重复读

这个冲突很有意思。

【定义】A事务访问一条数据后,B事务修改了这条数据,A事务再次访问这条数据发现前后两次相同的读取操作结果不一致

【讨论】在实际使用中,会有谁在一个事务中写前后两次去访问同一条数据这样的睿智的操作呢?在我看来,有一种说法是认可的。就是这种可重复读的属性保证的是在一个事务执行的过程中,所使用的查询过的数据都是不会改变的,否则它所做的所有操作都是错误的。但这和丢失更新不是一样了吗。也有人说,是用于主从同步的,这里我还没能理解。

同一个任务两次 select 本身就是多余的。mysql 默认 rr 主要是为了主从同步时,采用逻辑 sql 同步时的一致性,因为主库的 sql 是并发执行的,会有两个事务一起再跑,从库同步是单线程的,不会有两个事务同时在跑,如果不是 rr,出现楼主的栗子说的情况时,主从数据就不一致了

有关幻读

【定义】A事务读取了满足条件的所有行后,B事务插入了一行数据,当A事务再次读取同样条件的数据时,发现多出了一条数据。

【讨论】又会有哪个睿智两次去读同样条件的数据呢?实际上,第二次读都不是指真的读,“插入”操作也会先“读”一下是不是已经存在条目了。

【举例】正常A事务的目的是,查询一次是否存在条目,若不存在,则插入条目;干扰B事务的目的是,直接插入条目。

时间片 正常事务A 干扰事务B 
 T1 START 
 T2  START
 T3 查询是否存在条目item 
 T4  插入条目item
 T5  COMMIT
 T6 插入条目item 
 T7 失败,ROLLBACK 

这就是幻读真实的例子,正常的事务在读取条目item后,发现不存在条目item,而在它插入的时候,却发现已经存在条目item,前后两次“读取”不一致,原因是事务B插入了一条item。这个事情造成的后果是,A事务的正常执行逻辑被干扰了。


转载请注明出处http://www.bewindoweb.com/194.html | 三颗豆子
分享许可方式知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议
重大发现:转载注明原文网址的同学刚买了彩票就中奖,刚写完代码就跑通,刚转身就遇到了真爱。
你可能还会喜欢
具体问题具体杠