如何 select 一行,锁定它,更新它,然后再次 select?
How to select a row, lock it, update it, then select again?
我有一个包含以下 3 列的 table:
- 任务(字符串)
- 状态(字符串)
- 日期(日期时间)
我想编写一个执行以下操作的查询:
- 选择第一行
WHERE status != "In-Progress"
按日期排序(最早的在前),锁定它-所以其他计算机运行这个查询并发读取不了。
- 更新 状态列,因此
status = "In-Progress"
。
- Return 行的列(类似于常规
Select *
语句)。
如何编写此查询?
我主要担心的是,无论有多少个并发实例 运行。
,该行仅由 1 台计算机提取
假设 table 名为“tbl”,PK 名为“tbl_id”:
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 上的相关回答:
我有一个包含以下 3 列的 table:
- 任务(字符串)
- 状态(字符串)
- 日期(日期时间)
我想编写一个执行以下操作的查询:
- 选择第一行
WHERE status != "In-Progress"
按日期排序(最早的在前),锁定它-所以其他计算机运行这个查询并发读取不了。 - 更新 状态列,因此
status = "In-Progress"
。 - Return 行的列(类似于常规
Select *
语句)。
如何编写此查询?
我主要担心的是,无论有多少个并发实例 运行。
,该行仅由 1 台计算机提取假设 table 名为“tbl”,PK 名为“tbl_id”:
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 上的相关回答: