postgres 中的锁定机制/postgres 中的死锁。[我正在使用 sqlalchemy]

Dar*_*ous 5 python postgresql sqlalchemy database-deadlocks flask-sqlalchemy

我对 sqlalchemy-psql 中的锁定机制如何工作感到非常困惑。我正在使用 sqlalchemy 和 postgres 运行 python-flask 应用程序。由于我有多个线程处理一些数据并在 psql 上更新它,所以我遇到了以下死锁:

2015-12-31 17:[错误](由于查询调用的自动刷新而引发;如果此刷新过早发生,请考虑使用 session.no_autoflush 块)(psycopg2.extensions.TransactionRollbackError)检测到死锁

详细信息:进程 22833 等待事务 14114188 上的 ShareLock;被进程 19759 阻止。

进程19759等待事务14114189上的ShareLock;被进程 22833 阻止。

这是否会导致僵局:

Thread 1                                       Thread 2                                   
| (start an sqlalchemy session)                |
 db.session()                                  db.session()
|(Using sqlalchemy)                            |
Update row1 of table1                          Update row2 of table 1
|                                              |
Update row2 of table1                          Update row1 of table1
|                                              |  
session.commit()                               session.commit()
Run Code Online (Sandbox Code Playgroud)

以下是我的问题的一些答案,但我无法将它们与 sqlalchemy 联系起来。

Anu*_*ain 4

在 PostgreSQL 中,行在更新时将被锁定——事实上,其实际工作方式是每个元组(行的版本)都有一个名为 xmin 的系统字段,以指示哪个事务使该元组成为当前元组(通过插入或更新) )和一个名为 xmax 的系统字段,用于指示哪个事务使该元组过期(通过更新或删除)。当您访问数据时,它会通过对照这些值检查活动“快照”来检查每个元组,以确定它是否对您的事务可见。

如果您正在执行更新,并且与您的搜索条件匹配的元组具有使其对快照可见的 xmin 和活动事务的 xmax,则它会阻塞,等待该事务完成。如果首先更新元组的事务回滚,则您的事务将唤醒并处理该行;如果第一个事务提交,您的事务将被唤醒并根据当前事务隔离级别采取操作。

显然,死锁是按不同顺序发生这种情况的结果。RAM 中没有行级锁,可以同时为所有行获取行级锁,但如果行以相同的顺序更新,则无法获得循环锁。不幸的是,建议的 IN(1, 2) 语法并不能保证这一点。不同的会话可能有不同的活动成本因素,后台“分析”任务可能会更改一个计划和另一个计划生成之间表的统计信息,或者它可能正在使用 seqscan 并受到 PostgreSQL 优化的影响,从而导致新的 seqscan加入已经在进行中的一项并“循环”以减少磁盘 I/O。

阅读此 http://elioxman.blogspot.in/2013/02/postgres-deadlock.html