在mysql中,select ... for update 仅适用于InnoDB,且必须在事务块中才能生效。Innodb引擎默认是行锁。
??Select ?.... ?from ?where ?.... ??for update 如果在where的查询条件字段使用了【主键|索引】,则此命令上行锁。否则,则命令上表锁。它是悲观锁的一种实现方式。
场景1:查询条件为主键
会话A: select * from tb_pab where id=1 for update;
会话B: update ?tb_pab ??set ?uname='bj' where id=1;==》出现阻塞
结论:select for update 查询条件为主键,则进行上行锁。
场景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 查询条件为索引,则进行上行锁。
场景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 查询条件非【主键|索引】,则进行上表锁。