Mysql锁

376 阅读4分钟

S 锁(共享锁,Shared Lock)

  • 作用:允许事务读取数据,但不允许修改数据。

  • 特点

    • 多个事务可以同时获得同一个数据的 S 锁。
    • 如果某个数据被加了 S 锁,则其他事务不能对该数据加 X 锁。
    • 主要用于读操作(SELECT ... LOCK IN SHARE MODE)。
  • 应用场景

    • 事务只需要读取数据,且希望确保数据在读取期间不会被修改。
    • 通常用于实现事务的一致性,例如:在读取的同时保证数据不被其他事务修改。
示例
START TRANSACTION;
SELECT * FROM orders WHERE id = 1 LOCK IN SHARE MODE;

在这个事务中,数据行 id = 1 被加了 S 锁,其他事务可以读取该数据,但不能对其加 X 锁或修改。


X 锁(排他锁,Exclusive Lock)

  • 作用:禁止其他事务同时读取或修改数据。

  • 特点

    • X 锁是排他的,一个事务持有 X 锁时,其他事务不能获得该数据的 S 锁或 X 锁。
    • 主要用于写操作(如 INSERTUPDATEDELETE)。
  • 应用场景

    • 事务需要修改数据,确保在修改期间数据不会被其他事务读取或写入。
示例
START TRANSACTION;
UPDATE orders SET status = 'completed' WHERE id = 1;

在这个事务中,数据行 id = 1 被加了 X 锁,直到事务提交或回滚之前,其他事务不能读取或修改该数据。

S 锁和 X 锁的兼容性

无锁S 锁X 锁
无锁
S 锁
X 锁
  • 无锁:任何事务都可以访问数据。
  • S 锁:允许其他事务添加 S 锁,但拒绝 X 锁。
  • X 锁:完全独占,其他事务不能访问数据。

S 锁与 X 锁的具体实现

MySQL 的 InnoDB 存储引擎使用多粒度锁:

  • 行级锁(Row-Level Lock) :对特定行加锁,粒度最细,锁冲突最少,但开销较高。
  • 表级锁(Table-Level Lock) :对整个表加锁,粒度粗,冲突多,但开销低。
  • 意向锁(Intention Locks) :为支持多粒度锁机制引入的锁,区分事务对表中具体行的操作意图。
锁冲突示例
  • 事务 A 对 orders 表中 id = 1 的行加了 S 锁;
  • 事务 B 试图对相同的行加 X 锁时,会被阻塞,直到事务 A 提交或回滚。

意向锁(Intention Lock)

意向锁是 MySQL 中为了支持多粒度锁机制(表级锁和行级锁同时使用)而引入的一种锁,它用于表明事务对表中某些行的操作意图。意向锁本身不会阻塞其他事务的操作,但它能快速判断是否有锁冲突,从而提高锁的管理效率。

意向锁的作用

意向锁的主要作用是:

  1. 快速检测锁冲突:通过检查表级别的意向锁,判断是否可以对整个表加锁,而无需检查表中每一行的锁状态。
  2. 支持多粒度锁并发:允许表级锁和行级锁同时存在,而不会导致冲突。

意向锁的类型

意向锁分为以下两种:

  1. 意向共享锁(Intention Shared Lock,IS)

    • 表示事务打算对表中的某些行加共享锁(S 锁)。
    • 事务可能在接下来对表中一个或多个行执行只读操作(SELECT ... LOCK IN SHARE MODE)。
  2. 意向排他锁(Intention Exclusive Lock,IX)

    • 表示事务打算对表中的某些行加排他锁(X 锁)。
    • 事务可能在接下来对表中一个或多个行执行写操作(如 INSERTUPDATEDELETE)。

意向锁的工作原理

  • 当事务尝试对某行加锁时,会首先对该行所在的表加意向锁。
  • 表级的意向锁不会与行级锁冲突,但会影响其他事务对该表加表级锁。
示例:
  1. 事务 A 对表 orders 中的某行加 S 锁;

    • 此时,事务 A 会对整个表加 IS 锁,然后对具体行加 S 锁。
  2. 事务 B 尝试对表 orders 加 X 锁(希望独占整个表);

    • 由于事务 A 已对表加 IS 锁,事务 B 会被阻塞,直到事务 A 提交或回滚。

意向锁的兼容性

当前锁类型ISIXSX
IS
IX
S
X
  • ISIX 不会互相阻塞,允许多个事务声明意图操作。
  • S 锁和 X 锁与意向锁会冲突,确保了数据的一致性和完整性。

意向锁的实际案例

示例 1:加行锁时的意向锁行为
START TRANSACTION;
-- 事务 A 对行加 S 锁
SELECT * FROM orders WHERE id = 1 LOCK IN SHARE MODE;
  • 事务 A 会对 orders 表加 IS 锁,然后对 id = 1 的行加 S 锁。
示例 2:表锁与意向锁的冲突
START TRANSACTION;
-- 事务 A 对行加 S 锁
SELECT * FROM orders WHERE id = 1 LOCK IN SHARE MODE;

-- 事务 B 尝试对表加 X 锁
LOCK TABLES orders WRITE;
  • 事务 A 已加 IS 锁,事务 B 的 X 锁请求会被阻塞,直到事务 A 提交或回滚。

总结

  • 意向锁是一种表级别的锁,用来标记事务对表中某些行的锁定意图。
  • 它不会直接限制行级操作,但会影响表级操作,确保表级锁与行级锁之间没有冲突。
  • IS 锁 表示即将加 S 锁,IX 锁 表示即将加 X 锁。
  • 通过意向锁,MySQL 实现了表级锁和行级锁的高效管理和并发控制。

Mysql加锁分析

加锁总结: