【发布时间】:2020-02-28 09:21:46
【问题描述】:
我遇到了以下代码并试图调试它,但我不明白为什么在这种情况下无法解锁锁:
const db = pgp(opts)
await db.one('SELECT pg_try_advisory_lock(1) AS lock') // returns true, and I can see the lock in the DB
// no await
db.tx(async t => {
const fingerprintIds = fingerprints.map(item => item.id)
sql = `UPDATE fingerprint SET blah=1 WHERE id IN ($(fingerprintIds:list)) RETURNING id`
const updatedFingerprintIds = await db.query(sql, { fingerprintIds }) // yes, it is not using the transaction object
// some other database calls
})
result = await db.one('SELECT pg_advisory_unlock(1) AS lock')
// result.lock === false, database logs the error: 'WARNING: you don't own a lock of type ExclusiveLock'
// lock still stays in the database (until the session ends)
当然,当我在db.tx 调用前面添加await,并在事务回调中使用t 时,它会按预期工作。
这是因为调用unlock 时 pg-promise 库处于事务状态吗?因为当我调用这一系列查询时,锁会按预期解锁:
SELECT pg_try_advisory_lock(1) AS lock;
BEGIN;
SELECT * FROM table;
SELECT pg_advisory_unlock(1) AS lock;
【问题讨论】:
-
我不知道 pg-promise,但是(会话级)咨询锁独立于事务。
-
Documentation explains 如何以及何时使用任务和事务。你为什么不按照这个模式?上面的代码很糟糕,因为你创建了一个事务上下文,然后实际上并没有使用它。
-
是的,我意识到 :) 这不是我的代码,但我试图理解这种行为
标签: postgresql postgresql-9.5 pg-promise