https://juejin.cn/post/6844903666332368909
文章详解了 MySql InnoDB 中的意向锁,介绍其为不与行级锁冲突的表级锁,分为意向共享锁和意向排他锁,意向锁之间兼容,与普通排他/共享锁互斥。它解决了表锁检测效率问题,保证并发性,实现行锁和表锁共存及满足事务隔离性要求。
关联问题: 意向锁能手动设置吗 意向锁如何提高效率 意向锁有哪些局限
InnoDB 支持多粒度锁(multiple granularity locking)
,它允许行级锁
与表级锁
共存,而意向锁就是其中的一种表锁
。
需要强调一下,意向锁是一种不与行级锁冲突表级锁
,这一点非常重要。意向锁分为两种:
意向共享锁(intention shared lock, IS):事务有意向对表中的某些行加共享锁(S锁)
-- 事务要获取某些行的 S 锁,必须先获得表的 IS 锁。
SELECT column FROM table ... LOCK IN SHARE MODE;
意向排他锁(intention exclusive lock, IX):事务有意向对表中的某些行加排他锁(X锁)
-- 事务要获取某些行的 X 锁,必须先获得表的 IX 锁。
SELECT column FROM table ... FOR UPDATE;
即:意向锁是有数据引擎自己维护的,用户无法手动操作意向锁
,在为数据行加共享 / 排他锁之前,InooDB 会先获取该数据行所在在数据表的对应意向锁。
我们先来看一下百度百科上对意向锁存在意义的描述:
如果另一个任务试图在该表级别上应用共享或排它锁,则受到由第一个任务控制的表级别意向锁的阻塞。第二个任务在锁定该表前不必检查各个页或行锁,而只需检查表上的意向锁。
设想这样一张 users
表: MySql,InnoDB,Repeatable-Read:users(id PK,name)
id | name |
---|---|
1 | ROADHOG |
2 | Reinhardt |
3 | Tracer |
4 | Genji |
5 | Hanzo |
6 | Mccree |
事务 A 获取了某一行的排他锁,并未提交:
SELECT * FROM users WHERE id = 6 FOR UPDATE;
事务 B 想要获取 users
表的表锁:
LOCK TABLES users READ;