mysql锁相关

优秀博客:https://www.zhihu.com/column/c_1104074839660294144

mysql锁是为了解决数据的一致性,但是过多加锁会造成阻塞,降低并发性能;基于此innodb存储引擎使用了mvcc(多版本控制)的方式减少加锁。

mvcc只针对rc、rr的隔离级别生效,并且rc隔离级别下读取的是最新的数据(即读取到的数据为最新一份快照数据),rr隔离级别下读取的是(当前事务开始时的快照数据)

mysql默认情况下快照读使用mvcc的模式,不加锁。

当前读时会对数据加锁,可以显示地加共享锁或者排他锁

所有的更新操作(增删改)都会加锁

锁和隔离性(下面的结论前提为隔离级别为RR的级别下):

快照读情况下:不存在幻读(连续两次读到的数据不同),mvcc来解决

当前读情况下:不存在幻读,next-key lock来解决,next-key lock除了给当前的索引范围(也可能为单条记录)加锁外,还会对两条记录的间隙加锁(辅助索引的情况)

但是注意一个问题,下面的情形可能导致数据更新丢失:

事务1读数据,存入内存

事务2读数据,存入内存

事务1根据内存值更新数据并提交

事务2根据内存值更新数据并提交

这样会造成事务1的更新丢失,解决方案:使用当前读的方式将记录加锁,让整个流程串行化

mysql默认使用next-key lock的方式加锁,如果是唯一索引则会值使用行锁。

死锁的两种形式:

1、事务循环依赖锁

2、一个事务的成功会造成另一个事务向后获取锁,此时mysql会主动死锁(也类似循环依赖)

第二种情况case:假设数据库中已经有记录 1  2  4  (id为唯一索引)

T1                                                                         T2

select * from t  where id = 4   for update

                                                                         select * from t  where id <= 4  lock in share mode; 阻塞,由于id=4的记录被事务一上了排他锁,但是此时T2已经获取了id<4记录的锁

insert into t   values(3)(死锁)

心有多大,天有多高,一起奋斗!!
原文地址:https://www.cnblogs.com/zhaolei1996/p/14906843.html