代码之家  ›  专栏  ›  技术社区  ›  Alin

knex在一个事务中一个接一个地执行多个操作

  •  2
  • Alin  · 技术社区  · 7 年前

    我需要对数据库运行多个操作,并且需要将它们全部放入一个事务中。 以下是我的做事方式,从我的测试来看,这似乎不正确。

    基本上,对于每个操作,我都有一个返回knex承诺的函数。根据参数,可能不需要实际执行任何操作,例如,如果没有要插入的行,则不需要执行任何操作

    function insertRows(rowsToInsert, trx){
      if (rowsToInsert && rowsToInsert.length>0){
         return knex.batchInsert(...).transacting(trx) 
      }else{
        //no need to run
        return Promise.resolve() //this is probably wrong
      }
    }
    

    //我在回报我的承诺 yield 此函数在 co

    function process(params){
      return new Promise(function (resolve, reject){
    
        knex.transaction(function(trx){
           return insertRows(rows, trx)
          .then(function (result){
              return insertRows(rows2,trx)
           }).then(function (result){
              return updateRows(rows3,trx)
           })
        }
      }
    }
    

    以这种方式运行时,我注意到有时在一次更新和一次插入之间会出现死锁,因此我相信我的操作不会一个接一个地发生,但可能是并行的? 我应该如何处理:

    • 一个事务中的多个操作
    • 手柄 then() 当行为空时,请跳到下一行 然后()
    1 回复  |  直到 7 年前
        1
  •  3
  •   GaryL    7 年前

    与@Mikael达成一致,您不需要 new Promise ,但我认为你也需要 return knex.transaction( ,以便在完成其他处理之前完成事务处理功能?

    function process(params){
      return knex.transaction(function(trx){
            return insertRows(rows, trx)
        }).then(function (result){
            return insertRows(rows2,trx)
        }).then(function (result){
          return updateRows(rows3,trx)
        });
    }
    

    因为你没有 return knex.transaction() ,此操作将与调用方的序列“断开连接”,并异步运行。

    你的 return Promise.resolve() //this is probably wrong 很好。您将在 else ,就像在 if 函数的一部分。因为该(子)函数仅在 Promise 。。。 .then ,实际上可以省略 其他的 子句,因为 。然后 语句自动将同步函数返回值转换为已解析的承诺。