2

对于sqlalchemy-psql中的锁定机制是如何工作的,我完全困惑不解。 我正在用sqlalchemy和postgres运行一个python-flask应用程序。因为我有多个线程处理的一些数据,并更新它的psql,我正在以下死锁:postgres中的锁定机制/ postgres中的死锁。 [我正在使用sqlalchemy]

2015年12月31日17:[ERROR](凸起作为查询调用的自动冲洗的结果;可考虑使用(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() 

Here一些答案,我的问题,但我不懂得如何跟他们的SQLAlchemy。

回答

2

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

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

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

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