select * from table for update使用行锁还是表锁,主要看是否使用到索引或主键,如果没有使用到索引或主键,则使用了表锁,如果使用到索引或主键,则是行锁
创建表

//id为主键  
//name 为唯一索引
CREATE TABLE `user` (
 `id` INT ( 11 ) NOT NULL AUTO_INCREMENT,
 `name` VARCHAR ( 255 ) DEFAULT NULL,
 `age` INT ( 11 ) DEFAULT NULL,
    `code` VARCHAR ( 255 ) DEFAULT NULL,
 PRIMARY KEY ( `id` ),
    KEY `idx_age` ( `age` ) USING BTREE 
) ENGINE = INNODB AUTO_INCREMENT = 1570068 DEFAULT CHARSET = utf8

行锁

使用主键或索引,select * from table for update使用行锁

select * from user where id=1  for  update
select * from user where name='zhangsan'  for  update

在执行select的同时开启事务,不提交事务,执行以下一条sql

update user set age=20 where id=1;
update user set age=20 where name='zhangsan';

会被阻塞一直无法更新数据,但是执行

update user set age=20 where id=2;

却是成功的,说明只阻塞了id=1或name=‘zhangsan’的行数据,所以是行锁

表锁

未使用索引或主键时,select * from table for update使用表锁

select * from user where code='abc' for update

执行sql前开启事务,不提交事务继续执行

update user set age=20 where id=2;
update user set age=18 where id=1;

会被阻塞无法更新数据

结果

如果查询条件用了索引或主键,那么select … for update就会进行行锁。
如果是普通字段(没有索引或主键),那么select … for update就会进行锁表。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐