注意 FOR UPDATE 仅适用于InnoDB,且必须在事务区块(BEGIN/COMMIT)中才能生效。
由于InnoDB 预设是Row-Level Lock,所以只有「明确」的指定主键,MySQL 才会执行Row lock (只锁住被选取的数据) ,否则MySQL 将会执行Table Lock (将整个数据表单给锁住)。
例如下面几种情况
A.假设有个表单products ,里面有id 跟name 二个栏位,id 是主键。
(明确指定主键,并且有此数据,row lock也就是行锁)
SELECT * FROM products WHERE id='3' FOR UPDATE;
B.(明确指定主键,若查无此数据,无lock)
SELECT * FROM products WHERE id='-1' FOR UPDATE;
C.(无主键,table lock)
SELECT * FROM products WHERE name='Mouse' FOR UPDATE;
D .(主键不明确,table lock)
SELECT * FROM products WHERE id<>'3' FOR UPDATE;
SELECT * FROM products WHERE id LIKE '3' FOR UPDATE;
要测试锁定的状况,可以利用MySQL 的Command Mode ,开二个视窗来做测试
MySQL update && select
CREATE TABLE `testupdate` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`val` bigint(20) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
update testupdate
set val = val+1
where id = 1 and @value := val+1;
select @value;