我正在加载测试我的node.js应用程序。在某些时候,我到达请求待处理的状态,我最好的猜测是因为锁定了事务。这是最后一条日志声明:
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
在pg_lock
中我通过以上查询获得了4行,GRANTED = true
,mode
ExclusiveLock
。
我应该从哪里开始寻找错误?
如果我在此锁定请求中进行了大量insert
和update
操作,那么隔离级别应为REPEATABLE READ
吗?
有没有办法调试/处理这种情况?
是否有任何机制可以超时锁定,以便可以轻松/自动释放应用程序并且不会阻止进一步的请求?
附带问题(因为我没有直接寻找工具):是否有任何工具可以监控并发现这种情况? (我希望使用Munin。)
我使用nodejs 4.2.1 with express 4.13.3,sequelize 3.19.3 as Postgres 9.4.1 ORM。
答案 0 :(得分:2)
欢迎使用PostgreSQL事务锁地狱:)
您可以花费大量时间来确定锁定的确切位置以及原因。但它很有可能帮助你解决问题。
解决此类情况的一般方法如下:
即使在精心设计的系统中,最后一步也常常成为必需品,不要让它吓到你;)
答案 1 :(得分:0)
我遇到了类似的情况,我开始请求相同的更新锁定的5个并行事务,第一个也继续需要更多postgres调用的工作。整个系统死锁,第一个事务在pg_stat_activity中的事务中列为空闲状态,并被授予对pg_locks中请求的所有锁的访问权限。
我认为发生了什么;
第一个事务获得了锁定,然后完成了查询。在此之后,它断开了与postgres的连接。
以下4个事务分别打开一个连接并锁定锁,这是由第一个事务持有的。
由于它们被阻止,第一个事务将被执行,当它尝试连接到postgres进行查询时,它会死锁,因为sequiezlize已经用完了连接。
当我更改了sequiezlize初始化并添加了更多连接到池时,默认为5,死锁消失。
我不确定是谁在使用第5个连接,或者由于某种原因,默认情况下是4而不是5,但似乎仍然勾选所有方框。
另一个解决方案是在postgres中使用NOWAIT选项,因此在请求锁定而不是获取锁定时,事务会中止,具体取决于您的用例。
希望如果其他人遇到同样的问题会有所帮助。