【问题标题】:Managing connection pool issue when updating several rows in oracle db with node.js and knex.js使用 node.js 和 knex.js 更新 oracle db 中的多行时管理连接池问题
【发布时间】:2021-07-08 05:09:18
【问题描述】:

我正在使用一个 Node.js 应用程序,它在 Oracle 数据库上插入和更新数据。有一种情况,我需要为单个 API 调用中的行数更新表的列值。但是,观察到这是一项耗时的任务,有时会达到连接最大池大小,从而出现以下错误。增加池大小也无济于事。

Knex: Timeout acquiring a connection. The pool is probably full. Are you missing a .transacting(trx) call?

为缓解此问题,为所有更新创建事务并使用 Bluebird.js 以并发方式执行更新调用,如下所示。

 knex.transaction((trx) => {
          ...........
          ...........
          Bluebird.map(allObjects, (item) => { 
            .......
            trx('Table_Name')
           .where('ID', item.ID)
           .update({abc: JSON.stringify(updatedAbc)}) 
           ........
           },
           { concurrency: 10 }).then(()=>{ trx.commit });;

但是,这也给出了上述问题。连续调用端点时,会出现超出池大小的问题。有没有更好的方法来解决这个问题。非常感谢您的帮助。谢谢。

【问题讨论】:

  • 你能跟踪/解释/调整 sql 吗?是否有正确的索引可用?更新期间会发生什么? (行的大小是否显着增长)
  • @ik_zelf 是的,要更新的行数。
  • 如果您要更新一个表中的多条记录,那么使用原始 node-oracledb 而不是 Knex 可能是一个很好的情况。 executeMany() 函数的性能明显优于对 execute() 的重复调用

标签: node.js oracle knex.js bluebird


【解决方案1】:

您至少缺少一些返回语句。此外,没有理由尝试在事务中同时更新多行,因为在事务中,所有查询都是按顺序执行的,如果有人尝试执行类似的操作,驱动程序只会将它们排队。

 // more or less fixed version of the code above:
 knex.transaction((trx) => {
   return Bluebird.map(d, (item) => { 
     return trx('Table_Name')
           .where('ID', item.ID)
           .update({abc: JSON.stringify(updatedAbc)});
    }, { concurrency: 10 }).then(() => console.log("transaction completed with success")).catch(err => console.log("Transaction was rolled back", err)));

更好的方法:


// throws an error if transaction did fail and was rolled back
await knex.transaction(async (trx) => {
  for (let item of allObjects) {
    await trx('Table_Name').where('ID', item.ID)
      .update({abc: JSON.stringify(updatedAbc)});
  }
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-24
    • 2015-06-15
    • 2013-05-07
    • 2018-09-10
    • 2020-05-25
    相关资源
    最近更新 更多