如何在并行更新中找到Postgres/PHP死锁?

如何在并行更新中找到Postgres/PHP死锁?,php,postgresql,doctrine-orm,database-deadlocks,Php,Postgresql,Doctrine Orm,Database Deadlocks,因此,我有一个运行PHP/PostgreSQL的在线游戏,其中一个更新过程偶尔会给我死区日志,如下所示: [2016-02-16 06:35:14]应用程序错误:条令\DBAL\DBALException:An 执行“更新PlayerCharacter集”时发生异常 定位距离=?,可见性=?其中id=?'带有参数[2167, 20,128]:SQLSTATE[40P01]:检测到死锁:7错误:死锁 检测到的详细信息:进程11691等待事务上的ShareLock 4173974; 被进程11706

因此,我有一个运行PHP/PostgreSQL的在线游戏,其中一个更新过程偶尔会给我死区日志,如下所示:

[2016-02-16 06:35:14]应用程序错误:条令\DBAL\DBALException:An 执行“更新PlayerCharacter集”时发生异常 定位距离=?,可见性=?其中id=?'带有参数[2167, 20,128]:SQLSTATE[40P01]:检测到死锁:7错误:死锁 检测到的详细信息:进程11691等待事务上的ShareLock 4173974; 被进程11706阻止。进程11706等待ShareLock 关于4173977号交易;被进程11691阻止。提示:请参阅服务器 记录查询详细信息

我试着查看服务器日志,但没有帮助

问题是我不知道这是如何发生的,因为虽然我可以看到代码中导致它的确切行,但我不理解它是如何发生的

代码更新了大量的行,这就是为什么我将处理拆分为6个并行进程,每个进程都会更新总数的一个子集。换句话说:不应该有其他进程更新主ID为128的行。那么,为什么会出现僵局

我怀疑a)有什么奇怪的地方,或者b)我的调度代码和其他进程中的一个bug正在更新第128行


我怎样才能知道发生了什么事?我能说服Doctrine或Postgres向我展示阻止交易吗?我是否可以以某种方式使事务无阻塞(因为这些是使用相同数学的并行进程,结果无论如何都应该是相同的,如果出于任何原因,结果不一样,我宁愿得到一个只差几个百分点的结果,而不是死锁)。

这就是为什么我将处理拆分为6个并行进程的原因,
不要这样做,你可能不需要它。死锁可能是由触发器或“级联”外键触发的代码引起的。相信我,我确实需要它。我做了很多昂贵的计算,在一个CPU上,游戏回合的处理时间超过30分钟。如果是外键造成的(我不使用触发器),我怎样才能知道是哪一个?如果您正在进行昂贵的计算:基于哪些数据?来自同一个表的数据?是的,来自此表的数据加上一些其他加入的数据。