NodeJS pg-promise如何使用Promise.all()处理事务

oyxsuwqo  于 2022-12-12  发布在  Node.js
关注(0)|答案(2)|浏览(170)

在我的一个项目中,我想使用pg-promise并行执行2个查询。我将这些查询 Package 在事务中,如下所述。我还使用Promise.all()来并行地进行数据库调用。我想了解这在内部是如何工作的,因为事务对两个查询都使用单个数据库连接,这是否意味着第二个查询只能在第一个查询完成后执行,因为txn由第一个查询保留?

const {TransactionMode} = pgp.txMode;

// Create a reusable transaction mode (serializable + read-only + deferrable):
const mode = new TransactionMode({
    readOnly: true,
    deferrable: true
});

db.tx({mode}, t => {
    return Promise.all([t.any('SELECT * FROM table1'),t.any('SELECT * FROM table2')]);
})
.then(data => {
   // success;
})
.catch(error => {
   // error
});

由于事务需要一个数据库连接来运行事务中的所有查询,因此了解它是如何完成的将是非常有趣的。

aij0ehis

aij0ehis1#

由于事务对两个查询都使用单个数据库连接,这是否意味着第二个查询只能在第一个查询完成后执行?
Postgres不支持在同一个客户端连接上的并行查询[1,2],当然也不支持在同一个事务中的并行查询。
1个字符
2:Postgres线协议确实支持流水线操作,但查询仍按顺序执行。

来自pg-promise作者的更新:

如果这是OP寻求的2个选择查询的最佳性能,那么最好的方法是使用multi

const [sel1, sel2] = await db.multi('SELECT * FROM table1; SELECT * FROM table2');

即您根本不需要为此进行事务处理。

hgc7kmma

hgc7kmma2#

pg-promise如何使用Promise.all()处理事务
它不是关于pg-promise如何处理事务,而是关于PostgreSQL事务如何处理查询。它做到了这一点,即它们总是顺序的。你不能在事务中并行任何东西。
pg-promise中并行执行2个类似查询的唯一方法是在根接口上执行:

const [sel1, sel2] = await Promise.all([
    db.any('SELECT * FROM table1'),
    db.any('SELECT * FROM table2')
]);

上面的代码将导致从池中分配两个连接,并并行执行查询。
一般来说,同时使用池中的多个连接并不是一个好的做法,因为连接是一种宝贵的资源,因此此类解决方案无法很好地扩展。您只能在例外情况下这样做。
而且,使用Promise.all会让整个事情变得毫无意义。使用Promise.race的解决方案会更适合这一点。

相关问题