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

标签 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;

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

那么,死锁有没有可能发生在这条语句中呢?据我所知,如果我们用 BEGIN/END 阻塞整个语句。会有同一个事务,不应该自己加锁。

最佳答案

肯定有一些其他进程在竞争相同的资源。这就是僵局的本质。像您显示的功能永远不会死锁。参见 comment by @kgrittn below ,他是 PostgreSQL 并发方面的专家。

您的 PostgreSQL 版本缺失。现代版本会引发详细错误消息。竞争资源的两个进程都使用标准日志设置详细列出。检查您的数据库日志。

您捕获错误的事实可能会阻止 Postgres 为您提供完整的详细信息。从 PL/pgSQL 函数中删除 EXCEPTION block ,如果您没有在数据库日志中获取信息并重试。

要缓解死锁,您可以做很多事情。如果您的所有客户端都以同步顺序访问资源,则不会发生死锁。本手册在关于 deadlocks 的章节中提供了解决大多数情况的基本策略.


至于8.3 版:考虑升级到更新的版本。特别是 8.4 版中的这项改进对您来说应该很有趣 (quoting the release notes):

When reporting a deadlock, report the text of all queries involved in the deadlock to the server log (Itagaki Takahiro)

此外,8.3 版将满足其 end of life in February 2013 .您应该开始考虑升级。

涉及 VACUUM 的死锁情况应该是 fixed in 8.3.1 .

关于postgresql - 在 PL/pgSQL 函数中检测到死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10077441/

相关文章:

sql - PostgreSQL 将数据聚合成单行

node.js - Sequelize - 嵌套关联查询只检索 1 个数组数据?

android - Android SQLite 中的并发问题

java - 为什么 java 中的 processBuilder 在 5 分钟后挂起?

c# - TransactionScope优先级(摆脱死锁情况)

mysql - 莫名其妙的 InnoDB 死锁

java - Hibernate 和 Postgresql 自动增量不同步

c# - 并发访问通用列表属性

Java ConcurrentLinkedQueue 行为异常

ruby-on-rails - PostgreSQL 全文搜索不从 Rails 中的表单获取参数