select查询语句是不会加锁的,但是select ....for update除外。
问题:
select .......for update加的是行锁还是表锁?
带着问题我们继续往下看。
验证:
建表sqlCREATE TABLE `atao` (
`id` INT ( 11 ) NOT NULL AUTO_INCREMENT,
`name` VARCHAR ( 255 ) DEFAULT NULL,
`age` INT ( 11 ) DEFAULT NULL,
PRIMARY KEY ( `id` ),
KEY `idx_age` ( `age` ) USING BTREE
) ENGINE = INNODB;
insert into atao(name,age) values ('唐三藏','20');
insert into atao(name,age) values ('孙悟空','500');
insert into atao(name,age) values ('猪八戒','100');
insert into atao(name,age) values ('沙悟净','50');
关闭自动提交:
案例一(主键):
开启第一个事务:
第二个事务去更新数据,被阻塞了,长时间拿不到锁报错。
我们再开启一个事务对另一条id为2的数据进行更新,更新成功。
案例二 (索引):
age创建了唯一索引。
开启第一个事务:
第二个事务去更新数据,被阻塞了,长时间拿不到锁报错。
我们再开启一个事务对另一条id为2的数据进行更新,更新成功。
案例三 (普通字段):
使用普通的字段name去操作,开启第一个事务。
第二个事务去更新数据,被阻塞了,长时间拿不到锁报错。
我们再开启一个事务对另一条id为2的数据进行更新,如果我更新成功了,就是锁行,失败了就是锁表。
结论:
如果查询条件用了索引/主键,那么select ... for update就会进行行锁。
如果是普通字段(没有索引/主键),那么select ... for update就会进行锁表。
来源:数据与人