mysql行级锁

只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!

当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,叫做“间隙(GAP)”,InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁(Next-Key锁)。

举例来说,假如emp表中只有101条记录,其empid的值分别是 1,2,…,100,101,下面的SQL:
Select * from emp where empid > 100 for update;
是一个范围条件的检索,InnoDB不仅会对符合条件的empid值为101的记录加锁,也会对empid大于101(这些记录并不存在)的“间隙”加锁。

https://blog.csdn.net/alexdamiao/article/details/52049993

---------------------

1.4  我们先执行 A语句:select * from table where id = '1001' for update 把1001加上锁,然后再执行 B语句:select * from table where id = '1001' and id ='1002' for update;这时候肯定查不出来,因为A已经把B要加锁的数据锁了,这样B联1002的数据都查不出来

解决方案:skip locked

如果把B语句改为:select * from table where id = '1001' and id ='1002' for update skip locked;意思就是执行的时候如果发现要查询的数据有锁,就把加了锁的数据排除,把剩下的数据加锁,然后查出来!

上面讲到了 for update 的四种方式,实际情况如何选择呢?

关于NOWAIT(如果一定要用FOR UPDATE,我更建议加上NOWAIT)
    当有LOCK冲突时会提示错误并结束STATEMENT而不是在那里等待(比如:要查的行已经被其它事务锁了,当前的锁事务与之冲突,加上nowait,当前的事务会结束会提示错误并立即结束 STATEMENT而不再等待).
    WAIT 子句指定等待其他用户释放锁的秒数,防止无限期的等待。
“使用FOR UPDATE WAIT”子句的优点如下:
1.防止无限期地等待被锁定的行;
2.允许应用程序中对锁的等待时间进行更多的控制。
3.对于交互式应用程序非常有用,因为这些用户不能等待不确定

4.若使用了skip locked,则可以越过锁定的行,不会报告由wait n 引发的‘资源忙’异常报告
https://blog.csdn.net/qq_32317661/article/details/80486102


版权声明:本文为zmm0420原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。