一 作用
1.1 结论
在mysql中,select ... for update 仅适用于InnoDB,且必须在事务块中才能生效。Innodb引擎默认是行锁。
Select .... from where .... for update 如果在where的查询条件字段使用了【主键|索引】,则此命令上行锁。否则,则命令上表锁。它是悲观锁的一种实现方式。
1.2 操作案例
1.2.1 查询条件为主键
场景1:查询条件为主键
会话A: select * from tb_pab where id=1 for update;
会话B: update tb_pab set uname='bj' where id=1;==》出现阻塞
结论:select for update 查询条件为主键,则进行上行锁。
1.2.2 查询条件为唯一索引
场景2:查询条件为唯一索引
会话A: select * from tb_pab where code='001' for update;
会话B: update tb_pab set uname='bj123' where id=1;==》出现阻塞
会话C: update tb_pab set uname='bj123' where id=2; 非阻塞
结论:select for update 查询条件为索引,则进行上行锁。
1.2.3 查询条件为普通字段,不加索引和主键
场景3:查询条件为普通字段,不加索引和主键
会话A: select * from tb_pab where name='sh' for update;
会话B: update tb_pab set uname='sh2' where id=1;==》出现阻塞
会话C:update tb_pab set uname='sh2' where id=2;==》出现阻塞
结论:select for update 查询条件非【主键|索引】,则进行上表锁。
SELECT...FOR UPDATE_select for update-CSDN博客
1.2.4 上锁和普通查询
a)一个会话用select x for update;一个会话执行select语句可以进行查询,可能存在数据不一致情况。例如:会话A:进行查询上行锁,处于未commit状态时,会话B进行select查询,会话B可以查询出内容。
b)一个会话用select x for update;一个会话执行update语句时则无法进行更新。如
A会话未提交;B进行更新时则阻塞;
A会话进行提交;B则进行更新提交查询出数据。
1.2.5 宕机情况
场景4:会话A上锁:
会话B阻塞
杀掉会话A后,会话B才能进行更新提交: