我想用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)