使用SELECT ... FOR UPDATE轮询值更改

时间:2019-02-25 12:22:51

标签: sql oracle

我有一个包含任务及其状态的表,类似于:

| task_id | task_status |
+---------+-------------+
|      71 |           1 |
|      85 |           3 |
|     110 |           2 |

让我们调用表TASKS

状态是一个枚举值,例如:

  1. = SCHEDULED
  2. = RUNNING
  3. = DONE

我需要轮询此状态,以通知用户他已开始的任务。目前,我只是使用while循环在服务器上对其进行轮询,例如以下伪代码:

status = old_status
while(timeout_not_expired and status==old_status) {
    status = get_status("SELECT task_status FROM TASKS WHERE task_id=%1", task_id)
    wait(check_interval)
}
return status

这很讨厌,不仅会向Oracle SQL服务器发送垃圾邮件,还会向我们的SQL查询日志发送垃圾邮件。

所以我做了一些谷歌搜索,发现了关于SELECT ... FOR UPDATE的信息。我试图运行以下语句:

SELECT 
task_status
FROM TASKS
WHERE task_id = 361
FOR UPDATE OF task_status

但是它立即返回。所以问题:

  1. 这甚至是FOR UPDATE的目的吗?
  2. 如果是,我如何使其超时等待行?

1 个答案:

答案 0 :(得分:1)

不,那不是该条款的目的。 From the documentation

  

通过FOR UPDATE子句,您可以锁定选定的行,以便其他用户在结束事务之前不能锁定或更新行。

您的查询选择该任务的当前状态并锁定该行,这主要是基于计划更新它,并且不希望其他人能够在您之间进行更改的情况select和后续的update

因此,执行完该查询后,没有其他人可以更新该任务的状态,直到您提交或回滚为止-与您要实现的目标相反。

您可以查看警报或排队机制,但是您可能想研究continuous query notification,尽管这样做可能会过分杀人。