【发布时间】:2014-03-31 18:41:55
【问题描述】:
我正在尝试使用 MYSQL 实现一个队列,并希望确保我正确理解 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 将在时间 t1 时执行 SELECT FOR UPDATE,在时间 t2 时执行 UPDATE。当机器 2 在 t1 和 t2 之间同时执行 SELECT FOR UPDATE 和 UPDATE 时会发生什么?会发生哪些情况?
- 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 在t1 和t2 之间执行SELECT FOR UPDATE 以及在t2 之后执行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)
【问题讨论】:
标签: mysql sql concurrency locking queue