数据库事务处理中关于并发控制的三大问题——丢失更新,未提交依赖和不一致分析问题
事务管理是数据库中很重要的一部分,也是非常精彩的一部分,集中解决了数据库在操作过程中关于效率和正确性的平衡,好比分蛋糕一样,又要分得快,又要得公平。
先解释两个概念
事务:由两个数据库操作(读和写)和一个非数据库操作(比如加减乘除)组成
四大特性ACID
性质 | 解释 |
---|---|
原子性 | 事务是不可分割的 |
一致性 | 事务是从一种一致的状态转换到另一种一致的状态 |
隔离性 | 事务的执行时相互独立的 |
持久性 | 成功提交的事务结果永久记录在数据库中 |
如果还不是很理解四个特性,可以参考这篇博客https://www.cnblogs.com/fjdingsd/p/5273008.html
今天我们要讨论的是并发控制,主要目标是使得多个用户能够并发访问数据。
为了达到这一效果,导致了以下问题的产生
丢失更新问题
这张图表现了两个事务T1,T2,并且他们基本并发执行,其中T1要慢一个t,假设bal初始为100,T1要减10,T2要加100,这类似于一个转账操作,无论顺序如何,结果都将是190,现在t4时刻,T2已经往bal里面加了100,此时是200,然后T1减10,但是T1减掉的是之前读取的bal,所以T1结果为90,T2的更新丢失
显然在这种转账的情况中,每一次写都对读有影响,所以每一笔转账都应该是原子操作(不可分割的操作)所以不能并发
未提交依赖(污读或是脏读)
如果在一个事务修改了数据,但是还没写回的时候,另一个事务就读取,就导致脏读。
比如说,我打算转10000块给我老爸,我刚输完密码,我老爸就收到了,但是一会后,由于我转账手续有问题,钱有退回来了,凭空多了10000
如图
T4修改了数据,此时还没有写回,但是T3已经读取了,而T4因为种种原因最后回滚了,也就是说修改失败,那么根据事务原子性,T4的所有修改都应该失效,但是在t5时刻,T3就读取了数据,导致脏读
以上两个问题,一个是读了更新前的数据,一个是读取了不该读的更新数据,都是和写有关,而对数据库只执行读操作的事务,如果顺序不好,也会产生不正确的结果
不一致分析问题
这里t1时刻x+y+z和为175,但是最后却变成了185,原因就在于t4时刻x-10,在t7时刻转给了z,但是t4时算入和的是原来的x,而t7时算入和的是转账后的z,T6读的顺序不一样,导致错误
此外还有模糊读,幻读等问题,本质上都是由于读写了同一个数据,但是由于并发,顺序出现了问题导致的
那你可能会说,那大不了不并发咯,一个一个来总不会错,可是这样简单粗暴的方法是在太影响效率,所以解决以上问题的方法就是并发控制技术,在下一篇博客有讲解