为什么在使用pg-promise进行交易时不能解除咨询锁?

问题描述 投票:0回答:1

我遇到了以下代码,并试图对其进行调试,但我不明白为什么在这种情况下无法将锁解锁:

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)

当然,当我在await调用之前添加db.tx,并在事务回调中使用t时,它会按预期工作。

发生这种情况是因为在调用unlock时pg-promise库处于事务状态吗?因为当我调用这一系列查询时,锁将按预期方式解锁:

SELECT pg_try_advisory_lock(1) AS lock;
BEGIN;
SELECT * FROM table;
SELECT pg_advisory_unlock(1) AS lock;
postgresql postgresql-9.5 pg-promise
1个回答
0
投票

这些锁定操作是当前连接会话所独有的,因此必须在同一连接会话内执行:

await db.tx(async t => {

    await t.one('SELECT pg_try_advisory_lock(1) AS lock');

    // execute all queries here, against 't' context;
    // ...

    await t.one('SELECT pg_advisory_unlock(1) AS lock');

});
© www.soinside.com 2019 - 2024. All rights reserved.