MySQL的锁机制

1.简介

MySQL的隔离性是由锁机制来保证的。锁是计算机协调多个进程或线程并发地访问某一资源你的机制。当多线程并发地访问某个数据时,尤其是在涉及金钱等安全敏感性数据的时候,需要保证数据在任意时刻最多只有一个线程可以对其进行修改,从而保证数据的一致性和完整性。

2.MySQL并发事务访问相同记录

并发事务访问相同记录可以大致分为三种情况:

2.1 读-读情况

读-读情况就是多个事务同时读取某条或多条相同的记录,由于读操作本身不会改变数据,因此是不存在任何数据安全问题的。

2.2 写-写情况

写-写情况即并发事务相继对相同的记录进行修改,在这种情况下会产生脏写的问题,任何一种隔离级别都不允许这种情况的产生,因此多个未提交的事务对同一条记录进行修改时,会让它们排队去执行,这个排队操作是通过锁来保证。这个所谓的锁其实是一个内存中的结构,在事务执行前本来是没有锁的,也就是说一开始是没有锁结构和记录进行关联的,如图所示:
在这里插入图片描述
当一个事物想要对这条记录进行改动的时候,首先会看看内存中有没有与这条记录关联的表结构,当没有的时候就会在内存中生成一个锁结构与之关联。比如事务T1需要对记录进行修改,就需要生成一个索结构与之关联,如下图:
在这里插入图片描述
在锁结构里有很多信息,为了简化理解,就拿两个比较重要的字段展示:

  • trx信息:代表这个锁结构是哪个事务生成的。
  • is waiting:表示当前事务是否在等待

当T1改动这条记录后,就会生成一个索结构与对应的记录进行关联,由于之前没有别的事务对该记录进行修改,所以is waiting是false。我们把这个场景称之为获取锁成功,之后就可以进行后续操作了。
在T1事务对该记录进行提交之前,事务T2也想对该记录进行修改,那么会先看看有没有锁结构与该记录进行关联,发现存在锁结构与该记录关联,那么T2会再生成一个自己的索结构与该记录进行关联,不过此时的is wating则为true,因为事务T2需要等待事务T1提交后才能对该记录进行修改。这个场景我们就称之为获取锁失败。如下图:
在这里插入图片描述
在事务T1提交后,会将与该记录关联的锁结构释放掉,然后查看是否有其他线程等待获取锁,发现T2事务在等待获取锁,会将T2锁结构的is wating改为false,且唤醒T2事务对应的线程,然后T2事务就可以正常执行了。如下图:
在这里插入图片描述

2.3 读-写情况

读-写或者写-读的情况,即一个事物在读取某条记录的时候,其他事务在对该记录进行修改,那么可能会产生 脏读、不可重复读、幻读的问题。MySQL在RR级别就解决了幻读的问题。

2.4 并发问题的读解决方案

怎么解决脏读、不可重复读、幻读的问题呢?有两种解决方案。

  • 方案一:读操作使用MVCC,写操作加锁
    所谓MVCC就是多版本并发控制,当进行常规的select操作(即简单的select 语句,不带for update或者lock in share mode)的时候,这时是快照读。此时在开启事务的时候会维护一个当前活跃事务(就是已开启但是还未提交的事务)列表-trx_list,里面的记录了当前活跃事务的id,由于事务的id是随着开启时间递增的,所以在最小事务id之前的事务都已经提交了,这些事务的id对于当前事务来说自然是可见的。最大事务id则是系统将要分配的下一个事务id,所以在最大事务id之后的事务对于当前事务来说都是未开启的,这些事务所做的修改对于当前事务来说自然是不可见的。同时记录在undo log中维护了各个事务对其修改的历史版本,所以根据事务id之间的关系就可以判断当前事务应该看到该记录的哪个事务版本的数据。由于当前读在开启事务的时候会生成一个ReadView,其中维护了上述的trx_list,且在本事务中多次进行查询都是用的最初的ReadView,因此在本事务中不论读多少次,某个记录的值都不会变,这就解决了脏读、不可重复读的问题。

相关推荐

  1. MySQL机制详解

    2023-12-10 18:34:04       20 阅读
  2. 寻秘:全方位揭秘MySQL机制

    2023-12-10 18:34:04       19 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-10 18:34:04       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-10 18:34:04       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-10 18:34:04       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-10 18:34:04       20 阅读

热门阅读

  1. 每日一道算法题 3(2023-12-11)

    2023-12-10 18:34:04       27 阅读
  2. 模电第一章-电路基本概念以及基本定律

    2023-12-10 18:34:04       38 阅读
  3. 笙默考试管理系统-MyExamTest----codemirror(51)

    2023-12-10 18:34:04       35 阅读
  4. “==”和“equals”的区别

    2023-12-10 18:34:04       42 阅读
  5. vscode插件webview和插件通信

    2023-12-10 18:34:04       41 阅读
  6. 大模型应用_chatgpt-on-wechat

    2023-12-10 18:34:04       40 阅读
  7. ESP32网络编程-OTA方式升级固件(基于Web浏览器)

    2023-12-10 18:34:04       38 阅读
  8. 如何选择Docker基础镜像

    2023-12-10 18:34:04       28 阅读
  9. 代码随想录 70. 爬楼梯

    2023-12-10 18:34:04       32 阅读
  10. 【前端设计模式】之责任链模式

    2023-12-10 18:34:04       49 阅读
  11. SAP-PP:超实用的表PP顾问必备

    2023-12-10 18:34:04       32 阅读