MySQL 中的锁与事务隔离


一、锁

1.1 行级锁和表级锁

  • 记录锁(Record Lock)只对当前操作的行进行加锁,能大大减少数据库操作的冲突,加锁粒度最小、并发度高,但加锁的开销也最大、加锁慢、会出现死锁。记录锁锁住的是索引而非记录本身。
  • 间隙锁(Gap Lock)锁定一个范围但不包括记录本身,其目的是防止其他事务在间隙中新增数据造成幻读。
  • 临键锁(Next-Key Lock)记录锁和间隙锁的结合,锁定一个范围,并且锁定记录本身,是 InnoDB 默认的锁,对于行的查询都是采用该方法,可以解决虚读和幻读。
  • 表级锁对当前操作的整张表加锁,锁定粒度最大的一种锁,它实现简单、加锁快、资源消耗较少,但并发能力低。

1.2 S、X、IS、IX、SIX 锁

  • S 锁(Shared Lock):阻塞其他事务写数据。若事务 T 对数据对象 A 上 S 锁,则其他事务只能再对 A 上 S 锁,而不能上 X 锁,直到 T 释放 A 上的 S 锁。这就保证了其他事务可以读 A,但在 T 释放 A 上的 S 锁之前不能对 A 做任何修改。通常该页被读取完毕,S 锁立即被释放。
  • X 锁(Exclusive Lock):阻塞其他事务读和写数据。若事务 T 对数据对象 A 上 X 锁,则只允许 T 读取和修改 A,其他任何事务都不能再对 A 加任何类型的锁,直到 T 释放 A 上的 X 锁。这就保证了其他事务在 T 释放 A 上的锁之前不能再读取和修改 A。
  • IS 锁(Intention Shared Lock):当事务准备在某条记录上加 S 锁时,需要先在表级别加一个 IS 锁。
  • IX 锁(Intention Exclusive Lock):当事务准备在某条记录上加 X 锁时,需要先在表级别加一个 IX 锁。
  • SIX 锁(Shared Intention Exclusive Lock):SIX 锁表示表级共享锁与意向排它锁的组合。它表示该事务要读整个表,同时会更新个别元组。

S 锁与 X 锁既可以是行级锁也可以是表级锁,IS 锁与 IX 锁默认是表级锁,意向锁的提出仅仅为了在之后加 S 锁和 X 锁时可以快速判断表中的记录是否被上锁,以避免用遍历的方式来查看表中有没有上锁的记录。同时,如果一个表中有多个行锁,他们都会给表加上意向锁,意向锁和意向锁之间是不会冲突的

在这里插入图片描述


二、事务隔离

2.1 并发事务问题

数据库并发使用时可能出现以下并发事务问题

  • 脏读:当一个事务读取另一个事务尚未提交的修改时,产生脏读。
  • 不可重复读(虚读):同一查询在同一事务中多次进行,在此期间由于其他事务提交了对数据的修改或删除操作,每次返回不同的结果
  • 幻读:同一查询在同一事务中多次进行,在此期间由于其他提交事务提交了对数据的插入操作,每次返回不同的结果
  • 丢失修改:多个事务同时操作同一数据时,每个事务都不知道其他事务的存在,最后进行更新的事务会重写其他事务的更新

幻读其实可以看作是不可重复读的一种特殊情况,单独区分幻读的主要原因是二者的解决方案不同。记录更新和删除时,通过记录锁即可解决并发事务问题,但是插入操作的并发安全必须借助于间隙锁或者临键锁。

2.2 隔离级别

为了解决上述并发事务问题,提出了事务的四种隔离级别

  • 读未提交:一个事务还未提交,它所做的变更就能被其它事务看到,所有并发事务问题都有可能发生
  • 读已提交:一个事务提交后,它所做的变更才能被其他事务看到,不允许脏读
  • 可重复读:对同一字段的多次读取结果都是一致的,不允许脏读、不可重复读
  • 串行化:最高的隔离级别,强制事务串行执行,不允许任何并发事务问题

在这里插入图片描述

部分数据库的默认隔离级别最高隔离级别

在这里插入图片描述

2.3 两阶段锁

两阶段锁(Two-Phase Locking,2PL)是一种常见的并发控制协议,用于管理数据库中的并发事务。大多数关系型数据库都以 2PL 作为其默认的或可配置的并发控制机制,并在不同的隔离级别下定义不同的 2PL 行为。

2PL 将锁处理分为了两个阶段:

  • 增长阶段:只允许事务从锁管理器中请求锁或者进行锁升级。
  • 收缩阶段:只允许事务释放或降级自己所持有的锁。

下图为 2PL 中事务的锁数量随时间的变化:

在这里插入图片描述

不过 2PL 本身还存在两个问题:

  • 在增长阶段,锁是逐渐获取的,这就很有可能出现多个事务交叉等待锁的情况,从而导致死锁。因此 2PL 需要辅以死锁检测,例如可以通过判断锁依赖图中是否又环来检测死锁,并终止环中的最年轻的事务。
  • 在收缩阶段,锁是逐渐释放的,这就有可能导致脏读,如果当前事务异常终止还有可能导致级联回滚,由此提出了强两阶段锁(Strong Strict Two-Phase Locking,SS2PL)。与 2PL 不同,SS2PL 会在收缩阶段一次性释放所有的锁,从而避免脏读。

下图为 SS2PL 中事务的锁数量随时间的变化:

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值