https://www.zhihu.com/question/51513268/answer/127777478
https://www.slideshare.net/billkarwin/innodb-locking-explained-with-stick-figures
意向锁的作用:
考虑这个例子:
事务A锁住了表中的一行,让这一行只能读,不能写。
之后,事务B申请整个表的写锁。
如果事务B申请成功,那么理论上它就能修改表中的任意一行,这与A持有的行锁是冲突的。
数据库需要避免这种冲突,就是说要让B的申请被阻塞,直到A释放了行锁。
数据库要怎么判断这个冲突呢?
step1:事务B判断表是否已被其他事务用表锁锁表
step2:事务B判断表中的每一行是否已被行锁锁住。
注意step2,这样的判断方法效率实在不高,因为需要遍历整个表。
于是就有了意向锁。在意向锁存在的情况下,事务A必须先申请表的意向共享锁,成功后再申请一行的行锁。
在意向锁存在的情况下,上面的判断可以改成:
step1:事务B判断表是否已被其他事务用表锁锁表
step2:事务B发现表上已经有其他事务的意向共享锁,说明表中有些行被共享行锁锁住了,因此,事务B申请表的写锁会被阻塞。
注意:申请意向锁的动作是数据库完成的,就是说,事务A申请一行的行锁的时候,数据库会自动先开始申请表的意向锁,不需要我们程序员使用代码来申请。
说明:
Before SELECT…LOCK IN SHARE MODE or other shared lock, request an intention shared lock (“IS”) on the table.
Before SELECT…FOR UPDATE, INSERT, UPDATE, DELETE, request an intention exclusive lock (“IX”).
IS and IX locks allow access by multiple clients. They won’t necessarily conflict until they try to get real locks on the same rows.
But a table lock (ALTER TABLE, DROP TABLE, LOCKTABLES) blocks both IS and IX, and vice-versa.
意向锁分为:意向共享锁 IS LOCK 、意向排它锁 IX LOCK
官方说明:
1.Before a transaction can acquire an S lock on a row in table t, it must first acquire an IS or stronger lock on t.
2.Before a transaction can acquire an X lock on a row, it must first acquire an IX lock on t.
锁兼容性关系:
X | IX | S | IS | |
---|---|---|---|---|
X | Conflict | Conflict | Conflict | Conflict |
IX | Conflict | Compatible | Conflict | Compatible |
S | Conflict | Conflict | Compatible | Compatible |
IS | Conflict | Compatible | Compatible | Compatible |