你还不知道「MySql中的锁🔐」么?

139 阅读2分钟

这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战

InnoDB中的锁

共享锁

  • 锁兼容:假设T1获得了第1行的共享锁,另一个T2也可以;立即获得第一行的共享锁,仅仅是读取第一行内容,所以内容没改变叫锁兼容
  • 锁不兼容:如果T3想获取第一行的排它锁,那么必须等T1、T2释放第一行的共享锁,这种叫锁不兼容

行级锁

  1. 共享锁(S Lock):允许事务读同一行数据
  2. 排它锁(X Lock):允许事务删除或更新同一行数据

表级锁

意向锁

  • 意向共享锁:事务想要获取一张表的某几行的共享锁
  • 意向排他锁:事务想要获取一张表的某几行的排他s锁

MVCC

多版本控制

  • 首先介绍快照数据,它是当前行数据之前的历史版本,每行数据可能有多个版本
  • 一行数据可能有多个快照数据,所以叫多版本技术,引出了多版本并发控制-MVCC

RR与RC级别下的不同

  • 在RC级别下,快照数据,非一致性读总是读被锁定行的最新一份快照数据
  • 而在RR下,非一致性读总是读取事务开始时候的行数据版本

看以下的例子(关闭自动提交)

  • 首先数据有

image.png

  • 在第一个会话中开启事务做操作

image.png

  • 在第二个会话中将xiaoff的id改成6

image.png

  • 这是再运行会话1中的sql还是查询的xiaoff的id为1
  • 因为修改了一次在会话2 中,在事务中,id=1加了一个X(排他锁)锁

一致性的非锁定读:读取当前执行行的数据,如果读取的正在执行的delete/update,这时读取操作不会因此等待行上的锁释放,会去读行的一个快照数据

剧情反转

  • 当会话2 commit以后,在执行会话1的SQLRC与RR情况就不同了

  • RC级别下,总是读最新的版本,如果行被锁定,那么读取该行最新的一个快照

  • 则在RC级别下,再在会话1查id=1 这条数据就会为空

  • 如果在RR级别下,它总是读开始时的行数据,所以查id=1那么依然显示

    id   name
    1    xiaoff
    

一致性锁定读

  • Innodb对于select语句支持两种一致性的锁定读

    • select xxx for update
    • Select xxx lock in share mode