mysql 中的锁
1、锁的类型
共享锁,容许事务读取一行数据
排他锁,容许事务删除或更新一条数据
多粒度锁定,这种锁定容许事务在行级上的锁和表级上的锁同时存在,为了反对在不同粒度上进行加锁操作,innodb 反对一种额定的锁形式,称之为意向锁
意向锁:意味着事务心愿在更细粒度上进行加锁
动向共享锁:事务想要获取一张表中的某几行的共享锁
动向排它锁:事务想要获取一张表中的某几行的排它锁
2、一致性非锁定读
是 innodb 通过多版本控制的形式来读取以后工夫数据库中行的记录。如果读取的行正在进行 update 或者 delete 操作,则不会期待以后行的排它锁开释。相同,innodb 会去读取一个行的快照版本。read committed 和 repeatableread 都是应用一致性非锁定度,不过 readcommitted 总是读取被锁定行的最新一份快照数据,repeatableread 总是读取事务开始时的数据版本。例如:A,begin;
select id from t where id = 1;
B,
begin;
update t set id = 3 where id=1;
此时 A 中再次 select id from t where id = 1; 不论是 readcommitted 还是 repeatableread 后果都为 1。Bcommit
此时 A 中再次 select id from t where id = 1;readcommitted 是 null,是 repeatableread 后果为 1。
3、一致性锁定读
select for update;
select Lock in share mode;
4、外键和锁
innodb 在增加外键的时候会被动给外键的列加上索引
对于外键的插入和更新须要应用一致性锁定读来查问父表
select Lock in share mode
A
begin;
delete from t where id = 3;
B
begin;
insert into t2 select(2,3);第二列是外键
A 会对 3 这行数据加上 x 锁,B 会对 3 这样数据加上 s 锁,加不上,无奈插入,如果不加 s 锁,那么新增胜利则会造成数据不统一;
5、锁的算法
行锁的三种算法
record lock: 单个行记录上的锁
GapLock: 间隙锁,锁定一个范畴,但不蕴含记录自身
Next key Lock:GapLock+recordLock, 范畴加记录自身。对于惟一索引,加的是 record lock
对于不同索引,加的是 NextKeyLock
insert into z values(3,1)
insert into z values(5,3);
insert into z values(7,6)
A select * from z where b = 3 for update;
首先用 recordLock 锁定 a =5, 而后用 nextKeyLock 锁定 b =3,(1,3] 和 (3,6)
如果不应用 nextKeyLock 那么 insert into z values(6,3) 能够胜利,那么 A 中再次执行同样的操作就会取得不同的后果,phantom problem.
用户能够通过 nextKeyLock 机制在应用层实现唯一性查看
select * from twhere col = xxx Lock in share mode;
if not found any row;
insert into table values();
6、脏读
7、不可反复读
8、失落更新