我在 PostgreSQL 中使用事务。事务是严肃数据库的必要组成部分。交易不可避免地导致“死锁”。死锁按原样记录为错误。我不想记录任何错误,所以我需要处理这些死锁。据称,死锁是通过检测它们、抑制错误并重试查询直到它通过而没有死锁来处理的。
到目前为止,一切都很好。
现在开始解决问题。我使用pg_query_params()
andpg_query()
向 PostgreSQL 发送查询。这两者都FALSE
在失败时返回,或者在成功时返回“查询结果资源”。当 PostgreSQL 检测到死锁时,这些函数因此返回 aFALSE
并且我的 PHP 错误日志会收到一堆关于死锁的噪音。
PHP手册是这样说的pg_last_error()
:
错误消息可能会被内部 PostgreSQL (libpq) 函数调用覆盖。如果 PostgreSQL 模块函数内部发生多个错误,它可能不会返回适当的错误消息。
因此它不可靠,不能使用。它继续说:
使用 pg_result_error()、pg_result_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 错误(通过使用自定义错误记录器并检查字符串)只会解决错误日志噪音的问题,但实际上不会使死锁查询重试,因此他们永远不会完成他们的工作,只是默默无闻忽略。