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、丢失更新
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。