在PL/pgSQL函数中检测到死锁

Sat*_*rom 13 postgresql concurrency deadlock plpgsql

我正在使用PostgreSQL数据库中的PL/pgSQL函数来解决死锁问题.请在代码块中找到SQL语句(只是示例):

BEGIN
UPDATE accounts SET balance = 0 WHERE acct_name like 'A%';
UPDATE accounts SET balance = balance + 100 WHERE acct_name like '%A';
EXCEPTION WHEN OTHERS THEN RAISE NOTICE SQLERRM;
END;
Run Code Online (Sandbox Code Playgroud)

我发现在这个语句运行期间发生了死锁.但我不确定是否有其他语句试图同时更新此表(因为我在我的日志记录系统中没有找到任何语句).

那么,这句话中是否可能出现死锁?据我所知,如果我们用BEGIN/ 阻止整个陈述END.将有相同的交易,不应自行锁定.

Erw*_*ter 18

肯定有一些其他进程竞争相同的资源.这就是僵局的本质.像你显示的功能永远不会死锁.请参阅下面的@kgrittn评论,他是PostgreSQL中的并发专家.

您的PostgreSQL版本丢失了.现代版本会引发详细的错误消息.标准日志记录设置详细列出了竞争资源的两个进程.检查数据库日志.

您发现错误的事实可能会阻止Postgres向您提供完整的详细信息.如果您没有在db日志中获取信息并再次尝试,请从plpgsql函数中删除EXCEPTION块.

为了缓解死锁,你可以做很多事情.如果所有客户端都以同步顺序访问资源,则不会发生死锁.该手册为解决大多数情况下,约章的基本策略死锁.


对于8.3版:考虑升级到更新版本.特别是版本8.4中的这种改进应该对您有意义(引用发行说明):

报告死锁时,将死锁中涉及的所有查询的文本报告给服务器日志(板垣孝宏)

此外,8.3版将于2013年2月完成使用寿命.您应该开始考虑升级.

涉及的僵局情况VACUUM应该在8.3.1中得到修复.

  • 无论触发器如何,事务都不会与自身发生死锁.版本8.3.6*可能*在8.3生命周期中已经足够早,前景进程和后台自动真空过程之间的交互的一些错误可能会死锁.更新到8.3.somethingrecent以消除这种可能性可能会有所帮助.计划升级到新的主要版本,然后在2月份达到8.3次EOL也是明智之举.http://www.postgresql.org/support/versioning/ (5认同)