本文首发于个人微信公众号《andyqian》, 期待你的关注 ~
前言
在数据库中,通常通过锁来解决并发下数据一致性问题,从而避免数据产生脏乱。在保证数据一致性问题的前提下,通过锁范围又分为不同种类,在 MySQL 中,存储引擎就支持不同类型锁。如: MyISAM 只支持表锁。InnoDB 支持:行锁,表锁,Gap 锁等等。今天就来聊聊 MySQL InnoDB 的 " 锁事" 。
锁类型
既然提到了锁,锁类型是逃不开的话题,在 InnoDB 中,行锁分为共享锁(Share) 和 排他 (Exclusive) 锁。其详细概念如下:
- 共享(Share)锁 :简称 (S) 锁, 持有该锁的事务允许读取行数据。
- 排他(Exclusive)锁:简称 (X)锁 持有该锁的事务允许 update 或 delete 行数据。
备注:
- 此处的行锁不能简单的理解为锁定一行数据,而是 行数据。行数据包括:单行,多行,理解这区别,对后面理解(Record 锁,Gap 锁)会有莫大的帮助。
兼容关系:
S 锁X 锁S 锁兼容不兼容X 锁不兼容不兼容
文字解析:
当事务 T1 在行 t 上持有 S (共享) 锁时,事务 T2 对行 t 上 请求持有锁的结果如下:
- 当事务 T2 请求获取 S (共享) 锁时,将立即授予,此时 事务 T1,T2 同时持有 S (共享) 锁。
- 当事务 T2 请求获取 X (排他) 锁时,此时T2 将会处于锁等待状态,等待事务T1 释放 S (共享)锁后再进行获取,如果T2 锁
例子: 事务1持有S 锁, 事务2 请求持有S 锁。
- 事务1
begin;
mysql> select * from t_base_info where oid = 1 lock in share mode;
+-----+----------+---------------------+---------------------+
| oid | name | create_time | updated_time |
+-----+----------+--------------------