- 行锁
- 意向锁(表锁)
- 一致性非锁定读
- 一致性锁定读
- 脏读
- 不可重复读
- 丢失更新
- latch:闩锁,轻量级,锁定时间短,性能高,目的是用来保证并发线程操作临界资源的正确性,通常没有死锁检测机制,分mutex(互斥量)和rwlock(读写锁)两种;
- lock:与事务相关,用来锁定数据库中的对象:表、页、行,一般仅在commit和rollback后释放(不同事务隔离级别的释放时间可能不同),有死锁检测机制;
lock | latch | |
对象 | 事务 | 线程 |
保护 | 数据库内容 | 内存数据结构 |
持续时间 | 整个事务过程 | 临界资源 |
模式 | 行锁、意向锁 | 读写锁、互斥量 |
死锁 | 通过waits-for graph、time out等机制进行死锁检测与处理 | 无死锁检测与处理机制,仅通过应用程序加锁的顺序保证无死锁的情况发生 |
存在于 | Lock Manager的哈希表中 | 每个数据结构的对象中 |
- 共享锁S Lock:允许事务读一行数据
- 排它锁X Lock:允许事务删除或更新一行数据
X | S | |
X | 不兼容 | 不兼容 |
S | 不兼容 | 兼容 |
- 兼容是针对同一行数据而言的;
- 兼容性很好理解,因为只有读读是兼容的,而读写、写写都是不兼容的;
- 意向共享锁IS Lock:事务想要获取一张表中某几行的共享锁;
- 意向排它锁IX Lock:事务想要获取一张表中某几行的排它锁;
IS | IX | S | X | |
IS | 兼容 | 兼容 | 兼容 | 不兼容 |
IX | 兼容 | 兼容 | 不兼容 | 不兼容 |
S | 兼容 | 不兼容 | 兼容 | 不兼容 |
X | 不兼容 | 不兼容 | 不兼容 | 不兼容 |

- read committed:总是读取被锁定行最新一份快照数据,因为它是读已提交,而已提交就是最新的快照数据(快照读),但由于当前事务还未结束,故不满足隔离性;
- repeatable read(Mysql默认隔离级别):总是读取事务开始时的行数据版本(当前读),所以它叫可重复读,满足隔离性;
select @@tx_isolation;
select @@global.tx_isolation;
SET session TRANSACTION ISOLATION LEVEL read committed;
SET global TRANSACTION ISOLATION LEVEL read committed;
- select … for update,X锁
- select … lock in share mode,S锁
- 脏页:缓冲池已经被修改的页,但是还没有刷新到磁盘,即数据库实例内存中的页与磁盘中的页是不一致的。脏页的刷新是异步的,不影响数据库的性能;
- 脏数据:指事务对缓冲池中行记录的修改,还没有被提交;
- 事务A开启事务,并修改了一行数据;
- 事务B开启事务,修改了同一行数据;
- 事务A提交;
- 事务B提交;
- 事务A开启事务,读取了一行数据,假设该行数据有一个age字段,且age=10;
- 事务B开启了事务,读取了同一行数据,即age=10。
- 事务A进行修改操作,使新age=原age+10,然后提交。
- 事务B进行修改操作,使新age=原age+20,注意原age,事务B使用的是自己一开始读取的10,而不是事务A提交后的20,因此修改后的age=30,然后提交;
- 将隔离级别设为序列化读;
- 对读取操作上排它锁,select … for update;
- record lock:记录锁,锁定记录本身;
- grap lock:间隙锁,锁定一个范围,不包含本身;
- next-key lock:锁定范围+本身,设计的目的是为了解决幻读现象;
主键id(int) | money(int) |
1 | 600 |
2 | 800 |
3 | 1000 |
4 | 1200 |
5 | 1500 |
注意:
- 锁定区间可以解决幻读问题;
- 索引记录的顺序是由b+树决定的;
- 当插入money=600时,它的next索引结点是800,800位于锁定范围内,因此插入时会阻塞;
- 当插入money=599时,next索引结点是600,600不再锁定范围内,因此可插入;
- 当插入money=1000时,next索引结点是1200,可插入;
- 将当前锁的粒度变粗。比如,数据库可以将表的1000个行级锁升级为一个页锁,防止系统使用太多的资源来维护锁,一定程度上提高了效率。
总结:
这张表我来解释一下:
比如事务A采用S锁读,且对id对加锁,则对应的sql语句是:select * from account where id=2 lock in share mode;
此时事务B若对相同行的数据(即id=2这行数据)做S锁读、X锁读、Update操作会遵循S、X锁兼容性规则,而由于id列是唯一索引,因此插入任何数据都不会阻塞。
转载请注明:XAMPP中文组官网 » Mysql锁原理深入解析latch与lock?