Mysql InnoDB多版本并发控制MVCC
参考书籍《mysql是怎样运行的》系列文章目录和关于我
一丶为什么需要事务隔离级别mysql是一个客户端/服务断软件,对于同一个服务器来说,可以有多个客户端进行连接,每一个客户端进行连接之后就形成一个会话,每一个客户端都可以在自己的会话中向服务器发出请求语句,一个请求语句可能是某一个事务的一部分,服务器可以同时处理多个事务 。
如果事务时一个接着一个进行,那么下一个事务是在上一个事务的一致性前提下进行的,就没用一致性的问题,但是事务是并发进行且可能访问到相同的数据这时候就会出现如下问题

文章插图
可以看到AB最开始总和13元,最后AB总和18元,银行血亏五元,这显然违背了一致性——钱的总量不变 。这就是并发情况下两个事务的影响,所以需要事务隔离让事务隔离的进行,互不干涉 。
1.实现事务隔离的方式:串行执行最简单直接的方式,同一时间只能有一个事务运行,这样必然不会有上述不一致的情况,但是大大降低了吞吐率并增加了事务的等待时间
2.实现事务隔离的方式:可串行执行并发事务之所以出现不一致的情况,就是由于多个事务访问相同的数据,需要实现多个事务在访问相同数据的时候进行限制,比方说上图中事务2想访问A账户的值需要等待事务提交事务之后,这样可以让并发事务的执行如同串行执行的效果一样 。
二丶并发事务执行的问题:脏写,脏读,不可重复读,幻读1.脏写一个事务修改了另外一个未提交事务修改过的数据
- 脏写导致一致性无法保证
文章插图
上图事务A和事务B都更新紫色数据,其中事务A首先更新为A,然后事务B过来更新为B,这时候事务A回滚后更新为Null,事务 B 明明正常写了一行数据,但是写完之后发现值变了,有点丢失更新的意思 。(比如A表示余额,这时候在将余额A判断是否足以支付,判断得到可以,事务B执行扣费写入A-5,商家收到5元,结果这时候回滚了,A变成Null,事务A中转钱的一方钱变为A,钱的总额变为A+5了)
- 脏写导致原子性受到破坏
假如上述的事务B还操作了另外的数据,比如插入一条数据C,并且更改为B写入C是在一个事务下面的,需要具备原子性,但是脏写让B的更改需要部分回滚为Null,这样插入C和更改B就不具备原子性(比如A表示余额,这时候在将余额A判断是否足以支付,判断得到可以,事务B执行扣费写入A-5,商家收到5元,结果这时候回滚了,A变成Null,这时候部分回滚,商家的5元没用回滚,商家的库存也没用回滚,原子性被破坏)

文章插图
比如事务A先写数据A,然后事务B督导数据A后在内存中使用A进行一系列操作(比如A表示余额,这时候在将余额A判断是否足以支付,判断得到可以)但是事务A这时候回滚了,事务B再次读取数据发现为null,这就是脏读 。
脏读可能引发一致性的问题:比如事务操作时修改x和y的值,并且二者总是相等的,A修改x为1,还没来得及修改y也没用提交事务,这时候事务B读取x=1,y=0,二者不等,事务B读取到了数据库不一致的状态,读取到未提交事务的值
3.不可重复读假如一个事务修改了另外一个事务未提交的数据,意味发生了不可重复读
经验总结扩展阅读
- C#多线程之线程基础篇
- 豆腐在冷藏室可以放几天
- 200ml牛奶是多少克
- 一碗米饭的热量是多少
- 45岁男士体脂率多少正常 45岁男人体脂率多少
- 70多岁还能骑自行车吗 70岁老人能骑自行车吗
- 虾干热量有多少 虾干的热量是多少
- 一个水煮蛋多少大卡
- 板栗放冰箱里能存放多久
- 螃蟹干放着能活多久