使用 PHP 的 pg_* 函数时,如何检测 PostgreSQL 中的死锁?



我在PostgreSQL中使用事务。交易是严肃数据库的必要组成部分。交易不可避免地导致";死锁";。死锁被记录为错误。我不想记录任何错误,所以我需要处理这些死锁。据称,死锁是通过检测它们、抑制错误并重试查询直到它在没有死锁的情况下通过来处理的。

到目前为止,一切都很好。

现在开始解决问题。我使用pg_query_params()pg_query()向PostgreSQL发送查询。这两者都在失败时返回FALSE;查询结果资源";一旦成功。当PostgreSQL检测到死锁时,这些函数会返回一个FALSE,我的PHP错误日志会收到一堆关于死锁的噪音。

PHP手册对pg_last_error():有这样的描述

内部PostgreSQL(libpq(函数调用可能会覆盖错误消息。如果PostgreSQL模块函数内部发生多个错误,它可能不会返回适当的错误消息。

因此它不可靠,无法使用。它接着说:

使用pg_result_error((、pg_resull_error_field((、pg_result_status((和pg_connection_status((可以更好地处理错误。

在查找了这些函数后,我惊恐地意识到(正如它所说(:

因为如果查询失败,pg_query((将返回FALSE,所以必须使用pg_send_query(和pg_get_result((来获取结果句柄。

pg_send_query()pg_send_query_params()依次是异步。我不需要也不理解这样的";异步;SQL查询。我不明白这怎么可能,也不明白为什么会有人想要它

最终的结果是,我再次发现自己被画到了一个角落,在那里,似乎唯一的出路就是爬进烟囱,把自己弄得又脏又乱。

我似乎被迫完全放弃pg_query_params()pg_query(),只是为了能够检测死锁。真的会是这样吗?我只能想象从发送的SQL查询中会出现什么新的错误;异步地";而不是在";"阻塞";,有序的方式。

为什么总是这样?每次我尝试做任何事情,无论多么基本或常见,它似乎总是被认为是一种"怪异边缘情况";给其他人。当然,必须有一种方法来检测死锁,而不是通过使用这些奇怪的"死锁"来危害我的整个应用程序的完整性;异步;直到昨天我才听说的功能?

即使我使用它们,我仍然不清楚如何准确地检测到死锁。他们希望我解析错误并查找诸如"之类的英文字符串吗死锁";?这似乎也一点都不对;这感觉像是一个奇怪的黑客。

是否真的没有正确、干净的方法来检测死锁,以便正确处理它们?

简单地抑制PHP错误(通过使用自定义错误记录器并检查字符串(只会解决错误日志噪音的问题,但实际上不会让死锁的查询重试,因此它们永远不会完成自己的工作,只是被默默地忽略。

如果有人在乎,我最终"滥用";pg_send_*以阻塞的方式进行查询,只是为了能够正确地获取死锁(以及潜在的其他、未来的(错误。这是唯一的解决方案,尽管它让我感觉更";脏的";而不是对解决方案感到满意。也许看到这个自我回答会帮助将来的人意识到,以任何其他方式尝试都是完全浪费时间,因为我做了很长一段时间,但失败了。

最新更新