什么可能导致“ BEGIN”语句的“交易空闲”

问题描述 投票:2回答:2

我们有一个node.js应用程序,该应用程序通过pg-promise连接到Postgres 11服务器-所有进程都在docker容器中的单个云服务器上运行。有时我们遇到应用程序不再响应的情况。

上次发生这种情况,我花了一点时间通过pgadmin检查数据库,它显示连接为idle in transaction,并带有语句BEGIN和排他锁virtualxidenter image description hereenter image description here

我认为情况是这样的:

  1. 应用程序已通过向数据库发送BEGIN sql命令来启动事务
  2. db获得此命令并启动了一个新事务,因此获得了模式virtualxid的排它锁”>
  3. 现在数据库正在等待应用程序发送下一条语句(直到它收到COMMITROLLBACK)-然后它将释放模式virtualxid的排他锁”>
  4. 但是由于某种原因,它不再有任何声明:我认为node.js事件循环已被阻止-因为当我们看到这些锁时,node.js应用程序不再记录任何语句。但是网络服务器仍然收到请求并报告了一些upstream timed out请求。
  5. 这是否有意义(我真的不确定2.和3.)吗?为什么所有交易一开始都会被阻止?这是巧合还是显示的SQL可能是错误的?

    BTW:在此answer中,我发现可以设置idle_in_transaction_session_timeout,以便在超时后释放这些事务-很好,但是我尝试了解是什么导致了此问题。

我们有一个node.js应用程序,该应用程序通过pg-promise连接到Postgres 11服务器-所有进程都在docker容器中的单个云服务器上运行。有时我们遇到的情况是...

node.js postgresql pg-promise
2个回答
1
投票

交易完全没有阻塞。数据库正在等待应用程序发送下一条语句。

事务ID上的锁定只是事务相互阻止的一种技术,即使它们不竞争表锁(例如,如果它们正在等待行锁):每个事务在它自己的交易ID,并且如果必须等待并发交易完成,则可以仅请求锁定该交易ID(并被阻止)。


1
投票

您的解释是正确的。至于它为什么发生,这很难说。在您的应用程序中,或者在nodes.js或pg-promise中似乎存在某种错误(可能是未检测到的死锁)。您将必须在该级别进行调试。

© www.soinside.com 2019 - 2024. All rights reserved.