MYSQL事务和INNODB下的锁机制

一 什么是事务

想要真正了解事务,首先要知道什么是事务。常见例子就是转账,A转账给B一共2000元,这个操作其实有两步,第一步要从A的账户扣除2000元,第二步要给B的账号增加2000元,这两步操作合一,就成为了一个事务。那么事务有什么用,不难想象,在刚才的事务中,如果第一步操作成功后,银行系统崩溃,第二步没有成功,岂不出大事了。从这个例子可以看出,事务就是保证这两个关键操作要么都成功,要么都失败。

二 事务四大特性

从以上的例子和事务的功能来看,很容易就可以归纳出一些特性,例如操作必须都成功或者都失败,操作前后必须保证数据库的数据一致,不同事务不可以互相影响,操作完之后变化的数据应当被保存以防系统崩溃,那么因此可以归纳出以下四个特性:

  • 原子性

    • 这个特性如其名字一样好理解,事务是不可被分割的最小单位,事务中的操作要么全被执行,要么全部失败
  • 一致性

    • 事务执行前后除非修改了数据,否则数据应保持一致,多个事务对相同数据读取的内容也应该一致
  • 隔离性

    • 试想你在进行转账时,别人的转账操作也会改变你的账户余额你怕不怕 ,因此我们要确保事务之间不能相互影响
  • 持久性

    • 如果你进行完转账之后,银行系统崩溃,但你转账的操作没有被保存,系统恢复后无法查到你转账的记录,你上不上火。所以就需要持久性,事务执行后数据应当被保存,即使系统崩溃,您的操作也不会丢失。

三 事务四大隔离级别

  • Read Uncommited(读未提交)

    • 如其名,允许事务中读取其余事务尚未提交的操作,因此会带来脏读问题
    • 所谓脏读,举个例子,有人想和对象分手,写了一封分手信,左思又想还是不分了,分手信被撕掉了,他不想让任何人知道,也不会分手。但是他写信的时候,偏偏有个杀千刀记者也在他身边,那人读到他分手信,并且把这件事记录下来登了报,事情瞬间大发,他被迫分手了。这就是脏读,读到了别人尚未提交的操作。
  • Read Commited(读已提交)

    • 如其名,只允许事务读取已提交的操作,脏读问题不在了,但是有可能会产生不可重复读 和幻读
    • 所谓不可重复读,举个例子, 你和对象逛街,把钱包留给她去上了个厕所,去之前看了一下钱包,里面还有1000元,上完厕所回来再看一下钱包,只剩两毛,短短3分钟读到两个完全不一样的数据,就是不可重复读。
    • 所谓幻读:你去上完厕所回来之后,钱一分没少,还多了个钱包,你看着你对象笑呵呵的脸,是不是跟幻觉一样,其实是她自掏腰包给你又买了一个,这就是幻读。
  • Repetable-Read(可重复读)

    • 如其名,可以重复读,重复读啥呢,实际上它解决了不可重复读的问题,不可重复读的问题不就是你上厕所前后读到的钱包里的钱不一样嘛,那怎么保持一样呢,把钱包锁起来,保准你的钱不会少。但仍有可能幻读,为什么呢?因为你把钱包锁起来,你对象还是可以自掏腰包给你买个新的,回来之后,啪!跟幻觉一样,这种幻觉感还可能因为你对对象的不信任加强,是不是这个道理。
  • SERIALIZABLE(可串行化)

    • 最高的隔离级别,完全严格遵从ACID特性,事务之间互不干扰,逐个执行,这样可以解决脏读,不可重复读,幻读。
    • 例如上面你去上厕所前,叮嘱你对象上厕所的时候啥也别干,都等到你回来再做,那就不会出现惊喜了吧。

四 为什么要有事务隔离级别

之所以要有事务隔离级别,是因为根据不同的业务场景,我们需要避免脏读,幻读,不可重复读的情况不太一样,说白了,还是跟你要实现的业务有关系。例如,你是个大款,带对象逛街,你就不会在乎回来之后钱包里钱和之前不一样了,所以不用解决不可重复读。再比如你是女生,你不希望男生给你破费,所以你去上厕所得时候就得想办法解决你男朋友等会再给你买只口红的问题,也就是解决幻读问题,所以隔离级别是为了不同业务划分的。

五 INNODB默认隔离级别

INNODB引擎默认使用的RR隔离级别,和默认的RR隔离级别不同,INNODB的RR通过next-key lock解决了幻读问题,实现了事务的隔离性,所以INNODB中的RR隔离级别实际上他达到了SQL标准的SERIALIZABLE隔离级别。而隔离级别越高,申请的锁越多,因此大部分引擎都选择RC隔离级别,但INNODB的RR隔离级别不仅效果好,而且并没有引起性能损失,可谓强中强

六 INNODB锁机制

那为什么INNODB中RR隔离级别那么强?这就不得不说一说它用到的锁算法

  • record lock

    锁一条记录本身
  • gap lock

    锁一个范围,不包含记录本身
  • next-key lock

    锁一个范围,包含记录本身(就是record lock + gap lock)
    如上,INNODB对于行的查询用了next-key lock,但是如果你查的结果只有唯一属性(例如where…),就会降级到record锁。

猜你喜欢

转载自blog.csdn.net/weixin_44062399/article/details/123743537
今日推荐