Mysql
從多個事務更新相同的欄位
我有一項服務可以在數據庫中進行一些操作,一切正常,直到我嘗試並行發出兩個請求。
下面看sql調試日誌:
Executing (2c4cb493-7090-4a83-942a-1b3078a96a7b): START TRANSACTION; Executing (f49986af-9741-4f20-94ba-0644fbafea05): START TRANSACTION; Executing (2c4cb493-7090-4a83-942a-1b3078a96a7b): INSERT INTO `history` (`id`,`value`) VALUES (DEFAULT,'value data'); Executing (f49986af-9741-4f20-94ba-0644fbafea05): INSERT INTO `history` (`id`,`value`) VALUES (DEFAULT,'value data'); Executing (2c4cb493-7090-4a83-942a-1b3078a96a7b): UPDATE `table_2` SET `count`=count + 1 WHERE `id` = 1 Executing (f49986af-9741-4f20-94ba-0644fbafea05): UPDATE `table_2` SET `count`=count + 1 WHERE `id` = 1 Executing (2c4cb493-7090-4a83-942a-1b3078a96a7b): COMMIT; Executing (f49986af-9741-4f20-94ba-0644fbafea05): ROLLBACK; Deadlock found when trying to get lock; try restarting transaction
我不明白為什麼一個事務不等待另一個結束,而是拋出一個死鎖異常?
謝謝。
數據庫旨在支持多個並髮使用者。“等待其他事務完成”與該要求互斥。支持多個並髮使用者的能力是您使用數據庫而不是平面文件的原因。
你必須相應地設計你的算法。
在您的範例中,您希望序列化此過程。(注:序列化與設置配置參數相同
SLOW=TRUE
)您可以通過首先設置行鎖來序列化此過程
Table_2
。在MySQL(和其他 RDBMS)中,您可以通過SELECT ... FOR UPDATE
在事務開始時使用語法來做到這一點。該過程應如下所示:
START TRANSACTION; select count from test_2 where id=1 for update; INSERT INTO `history` (`id`,`value`) VALUES (DEFAULT,'value data'); UPDATE `table_2` SET `count`=count + 1 WHERE `id` = 1; commit;