SELECT ... FOR UPDATE SKIP LOCKED in REPEATABLE READ transactions
SELECT ... FOR UPDATE SKIP LOCKED in REPETABLE READ transactions
我的 PostgreSQL 10.5 数据库中有以下语句,我在 repeatable read
事务中执行它:
delete from task
where task.task_id = (
select task.task_id
from task
order by task.created_at asc
limit 1
for update skip locked
)
returning
task.task_id,
task.created_at
不幸的是,当我 运行 它时,我有时会得到:
[67] ERROR: could not serialize access due to concurrent update
[67] STATEMENT: delete from task
where task.task_id = (
select task.task_id
from task
order by task.created_at asc
limit
for update skip locked
)
returning
task.task_id,
task.created_at
这意味着事务回滚,因为同时有其他事务修改了记录。 (我觉得?)
这个我不太明白。不同的事务如何修改用 for update skip locked
选择并删除的记录?
This quote from the manual 讨论您的案例 完全:
UPDATE
, DELETE
, SELECT FOR UPDATE
, and SELECT FOR SHARE
commands
behave the same as SELECT
in terms of searching for target rows: they
will only find target rows that were committed as of the transaction
start time. However, such a target row might have already been updated
(or deleted or locked) by another concurrent transaction by the time
it is found. In this case, the repeatable read transaction will wait
for the first updating transaction to commit or roll back (if it is
still in progress). If the first updater rolls back, then its effects
are negated and the repeatable read transaction can proceed with
updating the originally found row. But if the first updater commits
(and actually updated or deleted the row, not just locked it) then the
repeatable read transaction will be rolled back with the message
ERROR: could not serialize access due to concurrent update
意思是,您的事务无法锁定开始的行 - 由于首先到达那里的并发写访问。 SKIP LOCKED
无法将您从中完全拯救出来,因为可能没有锁可以再跳过,如果该行已经被更改(并且已提交更改 - 因此锁已发布)自交易开始以来。
相同的语句在默认 READ COMMITTED
事务隔离下应该可以正常工作。相关:
我的 PostgreSQL 10.5 数据库中有以下语句,我在 repeatable read
事务中执行它:
delete from task
where task.task_id = (
select task.task_id
from task
order by task.created_at asc
limit 1
for update skip locked
)
returning
task.task_id,
task.created_at
不幸的是,当我 运行 它时,我有时会得到:
[67] ERROR: could not serialize access due to concurrent update
[67] STATEMENT: delete from task
where task.task_id = (
select task.task_id
from task
order by task.created_at asc
limit
for update skip locked
)
returning
task.task_id,
task.created_at
这意味着事务回滚,因为同时有其他事务修改了记录。 (我觉得?)
这个我不太明白。不同的事务如何修改用 for update skip locked
选择并删除的记录?
This quote from the manual 讨论您的案例 完全:
UPDATE
,DELETE
,SELECT FOR UPDATE
, andSELECT FOR SHARE
commands behave the same asSELECT
in terms of searching for target rows: they will only find target rows that were committed as of the transaction start time. However, such a target row might have already been updated (or deleted or locked) by another concurrent transaction by the time it is found. In this case, the repeatable read transaction will wait for the first updating transaction to commit or roll back (if it is still in progress). If the first updater rolls back, then its effects are negated and the repeatable read transaction can proceed with updating the originally found row. But if the first updater commits (and actually updated or deleted the row, not just locked it) then the repeatable read transaction will be rolled back with the messageERROR: could not serialize access due to concurrent update
意思是,您的事务无法锁定开始的行 - 由于首先到达那里的并发写访问。 SKIP LOCKED
无法将您从中完全拯救出来,因为可能没有锁可以再跳过,如果该行已经被更改(并且已提交更改 - 因此锁已发布)自交易开始以来。
相同的语句在默认 READ COMMITTED
事务隔离下应该可以正常工作。相关: