【发布时间】:2014-03-10 19:01:38
【问题描述】:
我的 Postgres 表:
表演者
- 身份证
- 排名
- group_id REFERENCES 组
表演
- 身份证
- 支付
- performer_id 引用表演者
组
- 身份证
我经常需要从一个组中选择所有表演者并更新他们的所有排名。但这通常会导致死锁,因为我正在执行 SELECT ... FOR UPDATE 选择,而其他线程同时是 INSERTing。
我经常看到的错误示例(在 Python SqlAlchemy 中):
DBAPIError: (TransactionRollbackError) deadlock detected
DETAIL: Process 83182 waits for ShareLock on transaction 14282922; blocked by process 83171.
Process 83171 waits for ShareLock on transaction 14282925; blocked by process 83182.
HINT: See server log for query details.
'SELECT performers.id AS performers_id, performers.rank AS performers_rank, performers.group_id AS performers_group_id \nFROM performers \nWHERE performers.group_id = %(group_id_1)s FOR UPDATE' {'group_id_1': 2}
我也有found 几个examples 这个behavior。
我该如何解决这个问题?我可以切换到不同的事务锁定级别吗?我宁愿不只是中止并不得不重试 - 我希望数据库为我处理这个争用。
一定有办法解决这个问题——我想做的很简单。
【问题讨论】:
-
插入
performances时,在每个不同的performer_id之后提交以避免与更新交叉锁定。它是ShareLock的事实强烈表明它是为 FK 拍摄的。 -
PostgreSQL 发回给客户端的错误信息中缺少其他事务的信息,避免信息泄露给客户端。 PostgreSQL 日志文件对这两个事务有什么说明?
标签: python sql postgresql concurrency sqlalchemy