间隙锁(Next-key Lock)
Oracle 锁定数据是通过需要锁定的某行记录所在的物理block
上的事务槽上表级锁定信息
MySQL 在指向数据记录的第一个索引键之前和最后一个索引键之后的空域空间上标记锁定信息(致命缺点是,不存在的键值也会被无辜的锁定, 而造成在锁定的时候无法插入锁定键值范围内的任何数据) - 为了解决幻读
锁
读锁:也叫共享锁(S锁),若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S 锁。这保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。
写锁:又称排他锁(X锁)。若事务T对数据对象A加上X锁,事务T可以读A也可以修改A,其他事务不能再对A加任何锁,直到T释放A上的锁。这保证了其他事务在T释放A上的锁之前不能再读取和修改A。
意向锁(Innodb为了兼容表级锁):
InnoDB有一个这样的规定:在加行级锁之前
自动会加意向锁
意向共享锁
(IS Lock):事务“想要”读取某几行数据。
意向排他锁
(IX Lock):事务“想要”写某几行数据。
加S Lock时,会先加IS Lock。加X Lock时,会先加IX Lock
考虑场景:我们使用LOCK TABLE语句希望对表A加读锁,这时我们应该先要判断是否有其他事务对表A进行写
没有意向锁:做法是遍历表A的所有行级锁,看是否有X锁。
有意向锁:做法判断一下表A是否有IX就可以了。就可以判断表A此时有没有在写的事务
行锁
操作对象是数据表中的一行
通过索引来实现行锁
,存在的问题
- query 没有命中索引,会走
表锁
- query 索引只是命中部分数据,但是还会锁定一片范围,由于间隙索引是
范围索引
导致 - 以b为索引条件对b做修改,会走
表锁
- 索引范围内
不存在
的键,被 Next-key Lock 范围锁定,导致无法插入新值 -
相同索引条件,不同数据变更也会
行锁