問題說明:
最近遇到一個問題,多個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 必須在事務內才能生效。