【问题标题】:How to select a row, lock it, update it, then select again?如何选择一行,锁定它,更新它,然后再次选择?
【发布时间】:2022-01-21 17:35:43
【问题描述】:

我有一个包含这 3 列的表格:

  1. 任务(字符串)
  2. 状态(字符串)
  3. 日期(日期时间)

我想编写一个执行以下操作的查询:

  1. 选择第一行 WHERE status != "In-Progress" 按日期排序(最早的在前),并锁定它 - 因此同时运行此查询的其他计算机无法读取它。
  2. 更新状态列,以便status = "In-Progress"。
  3. 返回行的列(类似于常规的Select * 语句)。

如何编写此查询?

我主要担心的是,无论有多少并发实例正在运行,该行只能由 1 台计算机获取。

【问题讨论】:

  • This answer 显示了一种锁定表格特定行的方法。
  • 您想对同样并行运行此进程并发现行锁定的另一个会话发生什么?
  • 理想情况下,我希望该行根本不会出现在其他查询中。

标签: sql postgresql concurrency sql-update queue


【解决方案1】:

假设一个名为“tbl”的表和一个名为“tbl_id”的PK:

UPDATE tbl
SET    status = 'In-Progress' 
WHERE  tbl_id = (
         SELECT tbl_id
         FROM   tbl
         WHERE  status <> 'In-Progress'
         ORDER  BY date
         LIMIT  1
         FOR    UPDATE SKIP LOCKED
         )
RETURNING *;

有关每个步骤的深入讨论,请参阅 dba.SE 上的相关答案:

【讨论】:

    猜你喜欢
    • 2012-09-22
    • 1970-01-01
    • 1970-01-01
    • 2014-05-14
    • 1970-01-01
    • 2021-01-04
    • 2013-10-15
    • 2020-03-05
    • 2014-08-26
    相关资源
    最近更新 更多