【问题标题】:How does SELECT FOR UPDATE actually work?SELECT FOR UPDATE 实际上是如何工作的?
【发布时间】: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 在 t1t2 之间同时执行 SELECT FOR UPDATEUPDATE 时会发生什么?会发生哪些情况?

- 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 在t1t2 之间执行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


    【解决方案1】:

    您需要在事务 (autocommit=0) 中执行这些操作,因为 SELECT FOR UPDATE 只在事务完成之前持有锁。

    您的任何情况都不会发生。事务不会立即失败,但它们可能会超时。

    如果事务 2 尝试锁定与事务 1 相同的记录(锁定发生在 SELECT FOR UPDATE 中),事务 2 将不得不等到事务 1 完成。如果达到锁定超时时间(innodb_lock_wait_timeout),则事务将超时(“失败”)。

    确保您在任何时候想要选择记录并遵守您使用的任何当前锁定SELECT FOR UPDATE。没有FOR UPDATE 的普通SELECT 不会等待任何锁。

    显然,您应该尝试尽快完成任何交易。

    您的方法应该可以正常工作。您应该考虑在SELECT FOR UPDATE 语句中检索主键值,然后通过UPDATE 语句中的主键值简单地引用记录。

    【讨论】:

      猜你喜欢
      • 2018-06-16
      • 2019-06-20
      • 2011-05-17
      • 2021-01-21
      • 2011-09-27
      • 2021-12-16
      • 2013-03-14
      • 2021-03-23
      • 2011-02-11
      相关资源
      最近更新 更多