postgresql - PostgreSQL中的子查询死锁
问题描述
在我认为由于排序而不会发生的情况下,我们遇到了死锁。
2019-09-11T20:21:59.505804531Z 2019-09-11 20:21:59.505 UTC [67] ERROR: deadlock detected
2019-09-11T20:21:59.505824424Z 2019-09-11 20:21:59.505 UTC [67] DETAIL: Process 67 waits for ShareLock on transaction 1277067; blocked by process 35.
2019-09-11T20:21:59.505829400Z Process 35 waits for ShareLock on transaction 1277065; blocked by process 67.
2019-09-11T20:21:59.505833648Z Process 67: UPDATE "records" SET "last_data_at" = '2019-09-11 20:21:58.493184' WHERE "records"."id" IN (SELECT "records"."id" FROM "records" WHERE "records"."id" IN ($1, $2) ORDER BY id asc)
2019-09-11T20:21:59.505843428Z Process 35: UPDATE "records" SET "last_data_at" = '2019-09-11 20:21:58.496318' WHERE "records"."id" IN (SELECT "records"."id" FROM "records" WHERE "records"."id" IN ($1, $2) ORDER BY id asc)
在这里,由于(诚然不必要的)子查询中的 id 将被排序,我认为死锁不应该是可能的。不IN
遵循传递数组的顺序?如果没有,我该如何解决这个问题?
(子查询来自我们的 ORM。)
解决方案
你使用的 ORM 是什么?
您可以使用咨询锁定来缓解死锁:
UPDATE
"records"
SET
"last_data_at" = '2019-09-11 20:21:58.496318'
WHERE
"records"."id" IN ($1, $2)
--This function will return TRUE if getting
--a lock is possible for current transaction
AND pg_try_advisory_xact_lock("records"."id")
老实说,恕我直言,依靠一个order by
条款来避免死锁似乎有点脆弱。
有关咨询锁定功能的更多信息,请点击此处。
推荐阅读
- tomcat - HTTP 请求/响应:端口 80 到端口 8085
- javascript - React 导入语句的标准方式
- java - 定义 jboss-web.xml 安全域会导致我的 EJB 缺少依赖项
- python - 如何从python中的字节数组中获取位?
- sql - 最近两个月的记录和他们在oracle中的差异
- postgresql - 使用自定义距离度量在 postgreSQL 中实现 KNN 的最佳方法是什么?
- r - 如何使用数据框中的变量创建函数
- c++ - 如何去除QTabWidget的空白区域
- angular - Ag-grid 禁用特定行中的按钮
- javascript - React-Redux:带有参数的 PATCH