Sad*_*han 5 postgresql postgresql-9.0
我有一个大表测试,其中 user_id 2 有 500000 条记录。所以我想以 100 条记录为单位删除这条记录,但出现错误。这是我的查询:
delete from test where test_id in (select test_id
from test where User_id = 2 limit 100 )
Run Code Online (Sandbox Code Playgroud)
错误:元组同时更新
这是什么问题。我怎样才能解决它。
您的普通子选择最多可获取 100 行,但不会锁定它们以防止写入访问。并发事务可以先更新或删除这些行中的一个或多个,然后DELETE
才能锁定行(至少在默认隔离级别下READ COMMITTED
)。这将导致您的错误消息。
为了防止这种竞争条件,请锁定SELECT
with FOR UPDATE
(或其他选项)中的行:
DELETE FROM test t
USING (
SELECT test_id
FROM test
WHERE User_id = 2
ORDER BY test_id -- acquire locks in consistent order!
LIMIT 100
FOR UPDATE -- lock rows
) x
WHERE x.test_id = t.test_id;
Run Code Online (Sandbox Code Playgroud)
以一致的顺序执行此操作,以防止以不同顺序收集锁并最终相互阻塞的多个事务之间发生死锁。
还有更好的解决方案。最好的选择是FOR UPDATE SKIP LOCKED
在 Postgres 9.5 或更高版本中使用:
考虑升级到当前版本的 Postgres。
最后我得到了解决方案,我只是在重新索引表,并且它现在工作正常。
reindex table test
Run Code Online (Sandbox Code Playgroud)
谢谢大家的建议。
归档时间: |
|
查看次数: |
11164 次 |
最近记录: |