MySQL-04a-锁概念

锁的概念

@toc:

  • 全局锁/表级锁/行锁;
  • 共享锁/排他锁;
  • 意向锁;
  • 两段锁协议;

➤ 按锁的范围分: 全局锁(数据库锁), 表级锁(表锁, meta锁), 行锁;

  • 全局锁: 锁住整个数据库实例, 例如Flush tables with read lock 整个数据库处于只读状态, 常用于全库备份;
  • 表级锁: 分为 表锁元数据锁
    • 表锁需要显式加锁: 例如 lock table t1 write 即给表t1加写锁, 允许读不允许写;
    • 元数据锁(MDL) 不需要显式加,
      • 当增删改查时, 数据库自动给表加MDL读锁, 可以增删改查数据, 但对修改表结构互斥;
      • 当修改表结构时, 数据库自动给表加MDL写锁;
  • 行锁: 行锁分为S锁/X锁 (类似读写锁), 根据数据库当前隔离级别的不同, 以及sql语句的不同, 加的锁也不同;
    • Serializable级别: 读加S锁, 写加X锁
    • RR/RC级别: 读不加锁(MVCC), 写可能加 X锁 和 间隙锁

MyISAM 不支持行锁, 不支持行锁意味着并发控制只能使用表锁,对于这种引擎的表,同一张表上任何时刻只能有一个更新在执行,这就会影响到业务并发度。InnoDB 是支持行锁的,这也是 MyISAM 被 InnoDB 替代的重要原因之一。

表锁的使用:

lock table xxx read; // 读锁
// 其他线程只可以对表select查询,查询立刻返回
// 但是无法对update/delete,操作会阻塞
unlock tables

参考:

  • 表锁/元数据锁 @link:: [[../49.Course/course.MySQL实战45讲]] 第6节;
  • 行锁 @link:: [[../49.Course/course.MySQL实战45讲]] 第7节;

➤ 按锁的特性分:

  • 共享锁(S锁): S锁类似读锁, 当线程1持有读锁, 不会排斥其他线程加读锁, 但排斥其他线程加写锁
    • 手动加 S 锁: select * from tableName where … lock in share mode
    • 自动加 S 锁: 串行隔离下, select语句加S锁
  • 排他锁(X锁): X锁类似写锁, 当线程1持有写锁, 排斥其他线程加读锁 or 写锁
    • 自动加 X 锁: 执行update, select .. for update,
  • 意向锁:
    • IS锁: 意向共享锁, 事务加”S行锁”前, 必须取得该表的 IS锁;
    • IX锁: 意向独占锁, 事务加”X行锁”前, 必须取得该表的 IX锁; // IS和IX都是表级锁
    • 「IX,IS是表级锁,不会和行级的X,S锁发生冲突。只会和表级的X,S发生冲突。」

@ref:

什么是两段锁协议

  • 两段锁协议( Two-Phase Locking, 2PL): 事务中, 可以分为加锁阶段 和放锁阶段, 所以叫两段锁协议;
  • 加锁阶段按照语句顺序进行加锁(例如事务中的 insert, update语句 到执行时才加相应的锁);
  • 放锁阶段: 解开所有的锁;
  • 也即行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。

使用MySQL实现乐观锁&悲观锁

  • 悲观锁: 假定会出现冲突, 首先尝试锁定数据(获得锁), 然后修改数据, 通常使用select .. for update进行加锁, 注意, 加锁是执行加锁语句的时候才加锁, 放锁需要等到事务结束后才能放锁.
  • 乐观锁: 假定不会出现冲突, 直接更新数据, 在更新数据的同时做判断是否冲突, 常见的MySQL乐观锁方式:
    • 使用version或timestamp, 先读取当前数据version/timestamp, 然后update .. where version=x的方式进行更新.

以更新商品库存为例( itemId primary key, count )说明乐观锁和悲观锁:

悲观锁更新库存:

select * from T where itemId=1 for update # 锁定
update T set .. where itemId=1

乐观锁更新库存: 通常使用version 或时间戳

select itemId, count from T where itemId = 1
update T set count=count-1 where itemId = 1 and count=x

@ref MySQL 乐观锁与悲观锁 - 简书