回顾

问题

  • 事务并发执行时可能带来各种问题,并发事务访问相同记录的情况大致可以划分为3种

    • 读-读情况:即并发事务相继读取相同的记录

      • 读取操作本身不会对记录有什么影响,并不会引起什么问题,所以允许这种情况的发
    • 写-写情况:即并发事务相继对相同的记录做出改动
      • 任何一种隔离级别都不允许这种问题的发生。所以在多个未提交事务相继对一条记录做改动时,需要让它们排队执行,这个排队的过程其实是通过来实现的。这个所谓的其实是一个内存中的结构,在事务执行前本来是没有锁的,也就是说一开始是没有锁结构和记录进行关联的
    • 读-写写-读情况:也就是一个事务进行读取操作,另一个进行改动操作
      • 这种情况下可能发生脏读不可重复读幻读的问题

解决上述问题方案

  • 读操作利多版本并发控制( MVCC ),写操作进行加锁
  • 读、写操作都采用加锁的方

一致性读(Consistent Reads)

  • 事务利用MVCC 进行的读取操作称之为一致性读,或者一致性性锁读,有的地也称之为快照读。所有普通的SELECT语句( plain SELECT )在READ COMMITTEDREPEATABLE READ隔离级别下都算是一致性读一致性读并不会对表中的任何记录做加锁操作,其他事务可以自由的对表中的记录做改动

锁定读(Locking Reads)

并发事务的读-读情况并不会引起什么问题,不过对于写-写读-写写-读这些情况可能会引起一些问题,需要使用MVCC或者加锁的方式来解决它们。在使用加锁的方式解决问题时,由于既要允许读-读情况不受影响,又要使写-写读-写 或写-读情况中的操作相互阻塞

  • 共享锁和独占锁

    • 共享锁 ,英文名:Shared Locks,简称S锁。在事务要读取一条记录时,需要先获取该记录的S锁
    • 独占锁 ,也常称排他锁,英文名:Exclusive Locks,简称X锁。在事务要改动一条记录时,需要先获取该记录的X锁
    • 上述两种锁的场景
      • 假如事务T1首先获取了一条记录的S锁之后,事务T2接着也要访问这条记录:

        • 如果事务T2想要再获取一个记录的S锁,那么事务T2也会获得该锁,也就意味着事务T1T2在该记录上同时持有S锁
        • 如果事务T2想要再获取一个记录的X锁,那么此操作会被阻塞,直到事务T1提交之后将S锁释放掉
      • 如果事务T1首先获取了一条记录的X锁之后,那么不管事务T2接着想获取该记录的S锁还是X锁都会被阻塞,直到事务T1提交
      • 故我们说S锁S锁是兼容的,S锁X锁是不兼容的,X锁X锁也是不兼容的
  • 锁定读的语句

    • 在采用加锁方式解决脏读不可重复读幻读这些问题时,读取一条记录时需要获取该下该记录的S锁,其实这是不严谨的,有时候想在读取记录时就获取记录的X锁,来禁用别的事务读写该记录

      • 对读取的记录加S锁

        • 也就是在普通的SELECT语句后边加,如果当前事务执行了该语句,那么它会为读取到的记录加S锁,这样允许别的事务继续获取这些记录的S锁(比方说别的事务也使用语句来读取这些记录),但是不能获取这些记录的X锁(比方说使SELECT ... FOR UPDATE语句来读取这些记录,或者直接修改这些记录)。如果别的事务想要获取这些记录的X锁,那么它们会阻塞,直到当前事务提交之后将这些记录上的S锁释放掉
      • 对读取的记录加X锁
        • SELECT ... FOR UPDATE; 也就是在普通的SELECT语句后边加FOR UPDATE,如果当前事务执行了该语句,那么它会为读取到的记录加X锁,这样既不允许别的事务获取这些记录的S锁(比方说别的事务使用语句来读取这些记录),也不允许获取这些记录的X锁(比方说使用SELECT ... FOR UPDATE语句来读取这些记录,或者直接修改这些记录)。如果别的事务想要获取这些记录的S锁或者X锁,那么它们会阻塞,直到当前事务提交之后将这些记录上的X锁释放掉
  • 写操作

    • 平常所用到的写操作DELETEUPDATEINSERT这三种:

      • DELETE:对一条记录做DELETE操作的过程其实是先在B+树中定位到这条记录的位置,然后获取一下这条记录的X锁,然后再执行delete mark操作。我们也可以把这个定位待删除记录在B+树中位置的过程看成是一个获取X锁的锁定读
      • UPDATE:
        • 在对一条记录做UPDATE操作时分为三种情况:

          • 如果未修改该记录的键值并且被更新的列占用的存储空间在修改前后未发生变化,则先在B+树中定位到这条记录的位置,然后再获取一下记录的X锁,最后在原记录的位置进行修改操作。其实我们也可以把这个定位待修改记录在B+树中位置的过程看成是一个获取X锁锁定读
          • 如果未修改该记录的键值并且至少有一个被更新的列占用的存储空间在修改前后发生变化,则先在B+树中定位到这条记录的位置,然后获取一下记录的X锁,将该记录彻底删除掉(就是把记录彻底移入垃圾链表),最后再插入一条新记录。这个定位待修改记录在B+树中位置的过程看成是一个获取X锁锁定读,新插入的记录由 INSERT操作提供的隐式锁进行保护
          • 如果修改了该记录的键值,则相当于在原记录上做DELETE操作之后再来一次INSERT操作,加锁操作就需要按照DELETEINSERT的规则进行了
      • NSERT:一般情况下,新插入一条记录的操作并不加锁,通过一种称之为隐式锁来保护这条新插入的记录在本事务提交前不被别的事务访问

前边提到的都是针对记录的,也可以被称之为行级锁或者行锁,对一条记录加锁影响的也只是这条记录而已,我们就说这个锁的粒度比较细;其实一个事务也可以在表级别进行加锁,自然就被称之为表级锁或者表锁,对一个表加锁影响整个表中的记录,我们就说这个锁的粒度比较粗。给表加的锁也可以分为共享锁S锁)和独占锁X锁

  • 多粒度锁

    • 给表加S锁

      • 如果一个事务给表加了S锁,那么:

        • 别的事务可以继续获得该表的S锁
        • 别的事务可以继续获得该表中的某些记录的S锁
        • 别的事务不可以继续获得该表的X锁
        • 别的事务不可以继续获得该表中的某些记录的X锁
    • 给表加X锁
      • 如果一个事务给表加了X锁(意味着该事务要独占这个表),那么:

        • 别的事务不可以继续获得该表的S锁
        • 别的事务不可以继续获得该表中的某些记录的S锁
        • 别的事务不可以继续获得该表的X锁
        • 别的事务不可以继续获得该表中的某些记录的X锁

【mysql】- 锁篇(上)的更多相关文章

  1. 精通MySQL之锁篇

    老刘是即将找工作的研究生,自学大数据开发,一路走来,感慨颇深,网上大数据的资料良莠不齐,于是想写一份详细的大数据开发指南.这份指南把大数据的[基础知识][框架分析][源码理解]都用自己的话描述出来,让 ...

  2. (6)MySQL进阶篇SQL优化(MyISAM表锁)

    1.MySQL锁概述 锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的计算资源 (如 CPU.RAM.I/O 等)的抢占以外,数据也是一种供许多用户共享的资源.如何保证数 据并 ...

  3. MySQL优化篇系列文章(二)——MyISAM表锁与InnoDB锁问题

    我可以和面试官多聊几句吗?只是想... MySQL优化篇系列文章(基于MySQL8.0测试验证),上部分:优化SQL语句.数据库对象,MyISAM表锁和InnoDB锁问题. 面试官:咦,小伙子,又来啦 ...

  4. 「MySQL高级篇」MySQL锁机制 && 事务

    大家好,我是melo,一名大三后台练习生,最近赶在春招前整理整理发过的博客~! 引言 锁锁锁,到哪到离不开这桩琐事,并发琐事,redis琐事,如今是MySQL琐事,这其中琐事,还跟MySQL另一个重要 ...

  5. v79.01 鸿蒙内核源码分析(用户态锁篇) | 如何使用快锁Futex(上) | 百篇博客分析OpenHarmony源码

    百篇博客分析|本篇为:(用户态锁篇) | 如何使用快锁Futex(上) 进程通讯相关篇为: v26.08 鸿蒙内核源码分析(自旋锁) | 当立贞节牌坊的好同志 v27.05 鸿蒙内核源码分析(互斥锁) ...

  6. 手把手教你定位线上MySQL锁超时问题,包教包会

    昨晚我正在床上睡得着着的,突然来了一条短信. 什么?线上的订单无法取消! 我赶紧登录线上系统,查看业务日志. 发现有MySQL锁超时的错误日志. 不用想,肯定有另一个事务正在修改这条订单,持有这条订单 ...

  7. mysql锁

    锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所有数 ...

  8. MySQL锁系列3 MDL锁

    http://www.cnblogs.com/xpchild/p/3790139.html   MySQL为了保护数据字典元数据,使用了metadata lock,即MDL锁,保证在并发的情况下,结构 ...

  9. Mysql锁机制--索引失效导致行锁变表锁

    Mysql 系列文章主页 =============== Tips:在阅读本文前,最好先阅读 这篇(Mysql锁机制--行锁)文章~ 在上篇文章中,我们看到InnoDB默认的行锁可以使得操作不同行时不 ...

  10. 07: mysql锁和事物隔离

    MySQL其他篇 目录: 1.1 MySQL中的事物 1.2 mysql中锁 1.1 MySQL中的事物返回顶部 1.InnoDB事务原理 1. 事务(Transaction)是数据库区别于文件系统的 ...

随机推荐

  1. linux下的c语言编程学习笔记

    视频参看csdn学院王阳和下面的linux环境下c语言编程基础相当的经典,其中王阳的视频讲的很好,相当的经典 编译hellogcc.c需要依赖/home目录下的头文件 为了避免同一个文件被includ ...

  2. RabbitMQ:五、高阶

    存储机制 持久化的消息和非持久化的消息都可以被写入到磁盘. 持久化的消息一开始就会写入磁盘,如果可以,也会在内存中保存一部分以提高性能,当内存吃紧时会从内存中清楚. 非持久化的消息一般存储在内存中,内 ...

  3. Vue数据更新页面没有更新问题总结

    Vue数据更新页面没有更新问题总结 1. Vue无法检测实例别创建时不存在于data中的property 原因: 由于Vue会在初始化实例时对property执行getter/setter转化,所以p ...

  4. mac下创建安卓应用 hello-world

    教程 https://www.jianshu.com/p/bf77cb5ce70b 需要注意的地方 jdk目录查找 jdk目录拷贝到tool目录下面(jdk可以拷贝,没有其他牵扯) https://w ...

  5. 如何获取自定义meta标签信息?

    <meta name="apple-itunes-app" content="app-id=432274380" /> 类似于这种meta信息,js ...

  6. Nginx 从入门到放弃(五)

    nginx的rewrite重写 nginx具有将一个路由经过加工变形成另外一个路由的功能,这就叫做重写. 重写中用到的指令 if (条件) {} 设定条件,再进行重写 set # 设定变量 retur ...

  7. python数据类型的72变

    输入数据的类型 input函数接收的数据默认为字符串类型 转换函数 通过转换函数实现接收其他类型的数据 1.接收整数:字符串→整型数据: int("整数格式的字符串") 2.接收小 ...

  8. Django快速开发实践:Drf框架和xadmin配置指北

    步骤 既然是快速开发,那废话不多说,直接说步骤: 安装Djagno 安装Django Rest Framework 定义models 定义Rest framework的serializers 定义Re ...

  9. 如何Simplest搭建个人博客

    前期 例如wordpress.hexo.hugo-- 准备 安装Node.js,安装Git,进入Hexo网站.进入Github网站进注册和登录. 建议买个阿里云服务器(学生最近好像是免费的) 开始搭建 ...

  10. 二叉树的镜像(剑指offer-18)

    题目描述 操作给定的二叉树,将其变换为源二叉树的镜像. 解析 先前序遍历这棵树的每个结点,如果遍历到的结点有子结点,就交换它的两个子节点, 当交换完所有的非叶子结点的左右子结点之后,就得到了树的镜像 ...