InnoDB共享、排他、意向、间隙锁机制

MySQL中的锁

MySQL中不同的存储引擎支持不同的锁机制。比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking),InnoDB存储引擎既支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁。

InnoDB锁

本文主要探讨InnoDB存储引擎中的锁机制,大致分文如下几种锁类型:

  • 共享锁和排它锁(Shared and Exclusive Locks)
  • 意向锁(Intention Locks)
  • 记录锁(Record Locks)
  • 间隙锁(Gap Locks)

共享锁和排他锁

InnoDB实现标准的行级锁定,其中有两种类型的锁: 共享(S)锁和排他(X)锁。

共享锁(s):又称读锁,允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。若事务T对数据对象A加上S锁,则其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。这保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。

A连接,开启事务,加S锁。

在这里插入图片描述

B连接,试图获取X锁时,被阻塞

在这里插入图片描述
直到A连接commit后,B连接才能获取X锁。

排他锁(x):又称写锁。若事务T对数据对象A加上X锁,事务T可以读A也可以修改A,其他事务不能再对A加任何锁,直到T释放A上的锁。可以自行演示,非常简单。

意向锁

InnoDB支持多种粒度锁定,允许行锁和表锁并存。意向锁是表级锁,指示事务稍后对表中的行需要哪种类型的锁(共享锁或排他锁)。有两种类型的意图锁:

  • 意图共享锁(IS)指示一个事务打算设置一个共享 上各个行锁定在表中。

  • 意图独占锁(IX)指示一个事务打算设定各行的排他锁在表中。

意向锁定协议如下:

  • 在事务可以获取表中某行的共享锁之前,它必须首先获取表中的IS锁或更高级别的锁。

  • 在事务可以获取表中某行的排它锁之前,它必须首先获取该表中的IX锁。

表级锁类型的兼容性汇总在以下矩阵中。

在这里插入图片描述

记录锁

记录锁定是对索引记录的锁定。例如, select * from table_lock_demo where id = 1 for update; 可以防止任务其他事务插入,更新或删除id=1的行记录。

记录锁总是锁定索引记录,即使表没有定义索引。对于这种情况,InnoDB创建一个隐藏的聚集索引并使用这个索引来锁定记录。

间隙锁

间隙锁定是对索引记录之间的间隙的锁定,或者是对第一个或最后一个索引记录之前的间隙的锁定。

如果执行如下语句,age上有一个普通索引。

select age from table_lock_demo where age BETWEEN 1 and 15 FOR UPDATE;

那么可以防止其他事务对age为1到15之间的数据进行修改、删除、插入。

测试的发现如果查询的是 select * from…则间隙锁不起作用,会锁表。

注意事项

  • InnoDB的行锁是基于索引实现的,如果不通过索引访问数据,InnoDB会使用表锁。
  • 在不同的隔离级别下,InnoDB的锁机制和一致性读策略不同。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码拉松

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值