平常当我们update一条记录时,如果我们使用的是mysql,并且使用了事务,那么会隐式的加上行锁或表锁。那么如何在代码中
显式的进行加锁呢。
select * from table for update即可显式的进行加锁,这是一种悲观锁。当我们在考虑接口幂等性时,其中一种就是通过悲观锁来解决的,但是悲观锁的效率比较低,有可能会造成大量的锁表,严重时会导致死锁的产生。
innodb中行锁是在索引的列才会产生,例如select * from table where id =?,这种情况下,select * from table where id = ? for update 锁住的就是行了,如果非索引列,例如select * from table where gender = ? 这种情况下锁住的就是整个表了。
下面来演示一下。
先打开窗口一
BEGIN;
SELECT
*
FROM
`user`
WHERE
id = 1 FOR UPDATE;
然后再打开窗口二
update `user` set `name` = 'ff' where id =1
窗口二出现
1205 - Lock wait timeout exceeded; try restarting transaction, Time: 51.056000s
可以看到,窗口一的事务没有提交时,id=1的这一行一直被锁住了。