MySQL for update

MySQL的存储引擎是InnoDB时 for update有行锁和表锁。
用法:

select ... for update

注意点

  • 仅适用于InnoDB,必须在事务块 begin/commit中才有效
  • 当有明确的主键/索引时是行级别的锁,否则是表级别的锁

验证

数据库表如下
MySQL for update_第1张图片

id是主键,name有索引,age和createtime无索引

验证1(有明确的主键/索引是是行级别的锁)

Terminal 1 执行

begin;
select * from bintest.afs_test a where a.name='HELLO01' for update; 

Termianl 2 执行

update afs_test a set a.name = 'HELLO02' where a.name = 'HELLO020';

该update会被正确执行,name被更改,说明表没有被锁

再执行

update afs_test a set a.name = 'HELLO010' where a.name = 'HELLO01';

这时Terminal2会被block知道Terminal 1执行 commit或者Terminal 2等待超时。

说明当Terminal 1对有索引的name执行查询for update是对行级别的锁

验证2(无明确主键/索引的是表级别的锁)

Terminal 1 执行

begin;
select * from afs_test a where a.age = 20 for update;

Terminal 2 执行

update afs_test a set a.age = a.age+5 where a.age=23;

age是无索引的,Terminal 2更新age=23的记录,与Terminal 1的查询age=20无行记录重合。但Terminal 2的执行会被block,知道Terminal 1执行 commit或者Terminal 2等待超时。说明对无明确主键/索引的是表级别的锁。

你可能感兴趣的:(mysql)