简单的UPDATE和DELETE语句能否在PostgreSQL中触发死锁和回滚?
在触发器中执行的简单简单的UPDATE和DELETE语句能否在PostgreSQL中触发死锁和回滚?,sql,postgresql,concurrency,triggers,deadlock,Sql,Postgresql,Concurrency,Triggers,Deadlock,在触发器中执行的简单UPDATE和DELETE语句在相同的表上同时执行其他更复杂的语句时会导致死锁或回滚吗 UPDATE "s_mat" SET "req_st" = my_st, "l_upd" = retr WHERE "req_id" = my_id; DELETE FROM "mat" WHERE "req_id" = my_id; 我是否应该预测这些语句可能出现的死锁或事务回滚异常?基本上是的。如果两个触发器同时在两个单独的事务中运行,我们将它们称为t1和t2: t
UPDATE
和DELETE
语句在相同的表上同时执行其他更复杂的语句时会导致死锁或回滚吗
UPDATE "s_mat"
SET "req_st" = my_st, "l_upd" = retr
WHERE "req_id" = my_id;
DELETE FROM "mat" WHERE "req_id" = my_id;
我是否应该预测这些语句可能出现的
死锁
或事务回滚
异常?基本上是的。如果两个触发器同时在两个单独的事务中运行,我们将它们称为t1和t2:
t1 t2
更新第x行
更新y行
删除y行
删除第x行
这将导致僵局。Postgres会自动检测到该情况,并中止除一个之外的所有竞争事务
如果所有代码都以相同(确定性)顺序处理行,则不会发生这种情况。但有时这无法保证
如果使用独占锁(按规范顺序)锁定要处理的所有行,则可以显著降低死锁的可能性
要绝对确定,请使用事务隔离运行。您必须为序列化失败准备代码,然后在这种情况下重试
可序列化模式下的事务速度较慢,只有在必要时才应使用。如果您没有面临繁重的并发负载,或者代码中没有关键的语句组合,那么使用默认的(更快的)隔离级别就可以了
优化代码的性能和最小化竞争条件的机会窗口可以大有帮助。除了总是以相同的顺序处理行之外,还可以使用将UPDATE
和DELETE
组合到一条语句中。不排除竞争条件,但最小化死锁的时间范围。示例及详细信息: