MYSQL SELECT FOR UPDATE
问题说明:
最近遇到一个问题,多个WORKER同时向MYSQL数据库请求任务,如何实现互斥?例如:
SELECT * FROM student WHERE id > 10 LIMIT 100;
UPDATE student SET status = 1 WHERE id > 10 LIMIT 100;
当有多个WORKER执行上面两条语句,那么很可能都执行同样的数据,造成线上问题,比如WORDER1执行SELECT之后,还没有执行UPDATE之前,WORDER2也执行了SELECT语句,造成问题。
那么这种情况可以使用SELECT ... FOR UPDATE,解决问题,当我读出数据的时候,锁表,那么其他的WORDER也就不能使用了。举例来说明:
1、建立测试表:
CREATE TABLE `test` ( `unit_id` int(11) NOT NULL AUTO_INCREMENT, `style` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`unit_id`) ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 插入数据: insert into test values (1,8),(2,1),(3,1);
2、测试:
2.1 在A客户端执行:
SET AUTOCOMMIT=0; BEGIN WORK; select unit_id,style from test where unit_id = 1 for update; mysql> select unit_id,style from test where unit_id = 1 for update; +---------+-------+ | unit_id | style | +---------+-------+ | 1 | 8 | +---------+-------+ 1 row in set (0.00 sec)
2.2 在B客户端执行:
mysql> select * from test where unit_id = 1 for update; ..........没有返回记录........
2.3 情况说明:
A客户端锁表成功,B客户端不能使用UPDATE进行类似修改的操作。注明 select from for update 必须在事务内才能生效。