MySql锁篇

MySql锁篇

latch和lock

锁的概念分为latch和lock

latch(闩):是一种轻量级锁的概念,分为互斥量和读写锁。主要用于保证并发线程操作临界资源的正确性,并且通常没有死锁检测的机制。
lock(锁):是一种重量级锁的概念,锁的对象是事务,锁定的是表、页、行。lock锁一般是在commit和rollback后释放

锁的类型

行锁一般分为共享锁(S锁)和排它锁(X锁)

在这里插入图片描述

innodb支持多粒度锁定,这种锁定允许事务在行级上的锁和表级上的锁同时存在,这种锁被称为意向锁。

若将上锁的对象看成一棵树,那么对最下层的对象上锁,也就是对最细粒度的对象进行上锁,那么首先需要对粗粒度的对象上锁,所以意向锁是表锁。innodb支持意向共享锁意向排他锁

  • 意向共享锁(IS Lock),事务想要获得一张表中某几行的共享锁
  • 意向排他锁(IX Lock),事务想要获得一张表中某几行的排他锁

由于InnoDB存储引擎支持的是行级别的锁,因此意向锁其实不会阻塞除全表扫以外的任何请求

在这里插入图片描述

一致性的非锁定读

一致性的非锁定读是InnoDB存储引擎通过行多版本控制(multi versioning)的方式来读取当前执行时间数据库中行的数据

如果被读取的行正在执行删除或者更新操作,这时读取不会去等待锁的释放,而是去读取行的一个快照,但并不是在每个事务隔离级别下都是采用非锁定的一致性读,在读已提交可重复读(默认事务)时会使用非锁定一致性读。读已提交每次读的是最新快照数据,可重复读每次读的是事务提交前行的数据版本快照

这里有提到各种事务隔离级别,在后面会进行说明

一致性锁定读

在某些情况下,用户数据库读取加锁保证数据逻辑的一致性

InnoDB支持两种一致性的锁定读操作:

  • SELECT…FOR UPDATE:对读取行加一个X锁
  • SELECT…LOCK IN SHARE MODE:对读取行添加一个S锁

这里是和上面的一致性非锁定读不冲突的,当加锁后,其他事务还是可以读取的快照版本的数据,但是不能修改改行数据

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

锁的算法

innodb中锁有3种算法:

  • Record Lock:单个行记录上的锁
  • Gap Lock:间隙锁,锁定一个范围,但不包含记录本身
  • Next-Key Lock∶Gap Lock+Record Lock,锁定一个范围,并且锁定记录本身

record lock:总会去锁住索引记录,如果没有任务索引,会锁定隐式的主键索引

next-key lock:Innodb对于行的读取都是采用的这种锁定算法,设计目的是为了解决幻读

这里有涉及到幻读的问题,那就先简单了解下什么是幻读。

幻读是指:在同一个事务下连续执行两次相同的查询语句,出现两次不同的结果

如以下场景:

  1. 表中只添加一个a=4的数据,这里的a不是唯一索引
  2. 开启事务
  3. 执行select * from table where a >2,读取到id=4的数据
  4. 其他事务添加一条id=5的数据(假设没有使用next-key lock算法,实际默认事务使用了该算法,不能插入)
  5. 在2中所提到的事务中再次执行select * from table where a >2,此时读取到了a=4和5的数据,产生了幻读

了解了幻读已及没有next-key lock下如何参生幻读后,我们来看看next-key lock是如何解决幻读的

next-key lock在上面说了,是锁定一个区间,包括记录本身。比如索引值是10,13,15,18,那么可能被锁住的区间就是

(-∞,10]、(10,13]、(13,15]、(15,18]、(18,+∞];

当是唯一索引时,为了提高效率,会进行降级为record lock

锁带来的问题

  • 脏读:一个事务可以读到另外一个事务中未提交的数据

  • 不可重复读:在一个事务中多次读取数据,在这过程中其他事务执行了DML操作并提交事务,在同一事务中读取到了两次不同结果

  • 丢失更新:一个事务的更新操作会被另一个事务的更新操作所覆盖,从而导致数据的不一致

脏读和不可重复读的区别:脏读是读到了其他事务还没提交的数据,不可重复读是读取到了其他事务提交后的数据;

其实这样看来不可重复读也不是啥大问题,但在next-key lock下其实是已经解决了不可重复读的问题

丢失更新:

  • 事务T1将行记录r更新为v1,但是事务T1并未提交。
  • 与此同时,事务T2将行记录r更新为v2,事务T2未提交。
  • 事务T1提交。
  • 事务T2提交。

实际上在默认事务下事务T1在更新r记录时,事务2是不能对该行记录进行更新的

以上是我作为一名后端开发,在看《MySQL技术内幕:InnoDB存储引擎》后总结的锁相关内容。该书还介绍了更多的关于锁相关的知识,但作为一名开发,我认为目前我所处的阶段,掌握以上知识点即可。上述内容如有错误,欢迎指出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值