我想用MYSQL實現一個隊列,並且想確保我正確理解SELECT FOR UPDATE
。SELECT FOR UPDATE如何實際工作?
我的表:
Table jobs
Fields: id (INT), state (VARCHAR), queued_time (TIMESTAMP)
當我插入一個作業,狀態QUEUED
。當我鎖定作業時,狀態變爲PROCESSING
。
我有多臺機器,每臺機器都使用相同的數據庫連接。當一臺機器準備搶東西從隊列中,它調用
SELECT FROM jobs WHERE state = "QUEUED" ORDER BY queued_time ASC LIMIT 1 FOR UPDATE; UPDATE jobs SET state = "PROCESSING" WHERE state = "QUEUED" ORDER BY queued_time ASC LIMIT 1;
查詢後,我檢查UPDATE
成功,如果它這樣做,我讓機器來處理由SELECT FOR UPDATE
返回的工作。
假設機器1和2已準備好從隊列中取出某些東西。隊列是這樣的:
id state queued_time
1 QUEUED 2014-03-30 20:04:43
2 QUEUED 2014-03-30 22:04:43
機1將在時間t2
執行SELECT FOR UPDATE
在時間t1
和UPDATE
。當機器2執行SELECT FOR UPDATE
和UPDATE
時,會發生什麼情況?t1
和t2
?哪些發生?
- Machine 1 ends up with job 1, and machine 2's `UPDATE` fails because machine 1 locked the row and never unlocked it (this is my current understanding)
- Machine 2 ends up with job 1, and machine 1's `UPDATE` fails
- Both machines end up with job 1
當機2執行t2
後t1
和t2
和UPDATE
之間SELECT FOR UPDATE
會發生什麼?哪些發生?
- Machine 1 ends up with job 1, and machine 2's `UPDATE` fails
- Machine 2 ends up with job 1, and machine 1's `UPDATE` fails
- Both machines end up with job 1 because machine 2's `UPDATE` succeeds since machine 1 release the lock (this is my current understanding)