事务
能够理解为一个 独立的
工做单元, 在这个独立的工做单元中, 有一组操做; 放在事务(独立工做单元)中的多个操做, 要么所有执行成功, 要么所有执行失败。难免俗套, 这仍是经过最经典的银行转帐
应用来解释一下mysql
假设有两个角色 'Iron Man'(余额500), 'Wolverine'(余额15), 如今 Iron Man
经过该银行应用给 Wolverine
转帐100元, 那么本次转帐操做至少须要三个步骤:sql
检查`Iron Man`余额`>=100`元 从`Iron Man`余额中`-100`元 给`Wolverine`余额`+100`元
独立的工做单元
来执行。在这个 独立工做单元
(即事务) 中的这三个操做, 只要有任何一个操做失败, 则事务就总体就是失败的, 那就必须回滚全部的步骤。在分析高并发事务的问题前, 咱们要先知道事务的几个标准特性, 由于一个运行良好的事务处理系统必须具有这些标准特性, 并且这些问题的解决离不开事务的这几个标准特性!!!数据库
一个不可分割的最小工做单元
, 整个事务中的全部操做要么所有提交成功, 要么所有失败回滚。对于一个事务来讲, 不能只成功执行其中的一部分操做, 这就是事务的原子性。Consistency 一致性
虽然可数据表中的数据可能一直在变化, 可是事务的一致性
特性会保证 数据库老是从一个一致性的状态 转换到 另外一个一致性的状态;segmentfault
好比在以前的转帐例子:并发
转帐前的一致性状态是: 'Iron Man'(余额500), 'Wolverine'(余额15) 转帐成功后的一致性状态是: 'Iron Man'(余额400), 'Wolverine'(余额115) 转帐若是失败的话, 一致性的状态应该回滚到转帐前的状态: 'Iron Man'(余额500), 'Wolverine'(余额15)
Isolation 隔离性高并发
-100
的余额才对隔离性
的 隔离级别
, 到时候就知道这里为何说一般来讲
对其余事务是不可见的; (也就是还有特例, 好比最低隔离级别 READ UNCOMMITTED
, 对其余事务的可见就形成了脏读问题
的出现)READ UNCOMMITTED
, READ COMMITTED
, REPEATABLE READ
, SERIALIZABLE
)Durability 持久性性能
一旦事务被最终提交, 则在事务这个独立单元中的全部操做所作的修改将会 `永久保存到数据库中`; (这里所说的`永久`应该能够理解为 被事务修改的数据 是真正存放到了表中, 而不是存放在了诸如临时表之类的地方)
在并发量比较大的时候, 很容易出现 多个事务同时进行 的状况。假设有两个事务正在同时进行, 值得注意的是: 它们二者之间是互相不知道对方的存在的, 各自都对自身所处的环境过度乐观, 从而并无对本身所操做的数据作必定的保护处理, 因此最终致使了一些问题的出现;
接下来, 在分析高并发事务的问题时, 你可能已经了解了一些关于锁的概念, 可是在分析这些问题的时候, 先不要带入锁的概念, 本小节只会列出问题, 并直接告诉你各个问题是使用事务隔离性的哪一个隔离级别解决掉的, 锁是解决方案, 若是带入锁的概念, 是没法去分析这些问题的。因此本节不须要带入锁
!
[下一篇文章]()将会分析这些解决方案(各隔离级别)具体是如何解决问题的。spa
若是mysql中一个事务A读取了另外一个并行事务B未最终提交的写数据, 那事务A的此次读取就是脏读
。(由于事务A读取的是'脏数据', 是'非持久性'的数据)code
脏数据
, 由于事务B最终会回滚这个数据, 因此若是事务A使用库存20进行后续的操做, 就会引起问题, 由于事务A拿到的数据已经和表中的真实数据不一致了。那么这个问题如何解决呢?
在MySQL中, 其实事务已经用自身特性(隔离性
的 -- READ COMMITED
或以上隔离级别)解决了这个问题;blog
**`READ COMMITED`级别保证了, 只要是当前语句执行前已经提交的数据都是可见的**。注意和`REPEATABLE READ`级别的区!!!
脏读问题
已经被彻底解决了, 那就意味着事务中每次读取到的数据都是 持久性
的数据(被别的事务最终 提交/回滚 完成后的数据)。隔离性
的 -- REPEATABLE READ
或以上隔离级别)解决了这个问题;REPEATABLE READ
级别保证了, 只要是当前事务执行前已经提交的数据都是可见的。注意和READ COMMITED
级别的区!!!对于幻读, 可能不少人常常和不可重复读区分不开, 详情能够参考本人写的此篇文章https://segmentfault.com/a/11...
高并发事务
的另外一个问题 -- 丢失更新问题
, 该问题和以前几个问题须要区分开, 由于解决方案不是一类!此类更新丢失问题, 没法依靠前三种隔离级别来解决, 只能用最高隔离级别 Serializable
或者手动使用乐观锁
, 悲观锁
来解决。
Serializable
在实际应用场景中并不被采用, 对于手动使用乐观锁
, 悲观锁
的方案, 将会在之后关于锁的文章中一并给出!参考资料: