vlambda博客
学习文章列表

MySQL漫谈:MySQL的事务隔离级别

谈到MySQL,就会扯到事务,事务最重要的就是这个事务隔离级别,所以搞明白这个对你不管是进一步了解MySQL,还是跟别人交流或者面试都很有帮助。

首先啥是事务,这是常听说,我们涉及到数据库的操作的过程中,我们希望这一些列操作要不然都是成功的要不然都是失败的,事务就是这个保证你一系列操作,“团结在一起,不成功便成仁,谁都跑不了”。涉及到更具体的操作,就是commit那一下之前的相关操作。

既然这样,事务为什么要隔离,还要搞一个隔离级别呢?也很好解释,因为数据库并不是只有一个用户用,很多用户用的同时,他们肯定也不会线下互相知会,谁先来谁后来。这就造成可能出现其他的一些状况

举个例子就好比,一张信用卡,你老婆是主卡,你是副卡,现在她在消费,你也在消费,账户余额是固定的,可能她卖了个包可能额度都要刷爆了,你在刷几块钱买冰可乐都买不了,还要想该如何分期压力小呢。如果两个事务不是隔离的,就会导致她包也买了,你冰可乐也买了,但是超过了你账户余额和账户额度。银行能干吗,肯定不能啊。

所以事务要隔离,其中一个原则就是ACID ,原子性(Atomic)一致性 (Consistency) 隔离性 (Isolation) 持久性 (Durability),保证帐要对得上,也就是冗余数据的一致性,不能随便出去坑人,也不能自己坑自己。

隔离级别都有啥?这时候我把我祖传的图给你搬出来了:


实际上第一个读未提交和最后一个序列化串行实际用的少,因为第一个不靠谱会出各种问题,等于没什么用,后一个太影响效率,一个一个去算客户可能没耐心,半天没变化以为你死机了呢。

这里遇到的问题要解释一下:

脏读:就是你能读到别人还没提交(commit)的数据

不可重复复读:就是这个数据是不变的,不是你查询查到是100,结果你+1的时候,发现这个100已经被别的事务改变了变成120了。------所以我们,不希望在一个事务中,看到的查询结果不一致,这就是不可重复读(我们可以在事务的隔离级别为REPEATABLE READ来完成)

幻读:这个要和上面的不可重复读对应起来

不可重复读:A事务执行中,B事务做了删除和修改,造成读到的结果不一样

幻读:A事务执行中,B事务新增了几条符合A事务的数据,造成结果不一样(注意这一条和上一条的加粗的字体。)

问题是insert,对于资源的锁,你光锁上你要的资源还不行,还要加一个间隙锁防止事务B给你加料。