2

0.19.4在节点 js 中使用 knex 10.x。我有 2 个 SQL 语句 - 插入和更新必须作为事务发生。

// Using Var, so that below code has access to this variable
var sqlStageInsert = kx('stage').insert({
  officeid: 'OFF000',
  taskid: 'T002',
});


var sqlTaskPcUpdate = kx('task')
  .update({ pc: 100})
  .where('task.taskno', taskno)
  .limit(1);

第一次尝试 - 第二次 SQLsqlTaskPcUpdate未执行

const sqlUpdateInsert = kx.transaction(function (trx) {
  sqlStageInsert.transacting(trx)
    .then(function () {
      console.log(sqlTaskPcUpdate.toString()); // This is outputing correct SQL
      return sqlTaskPcUpdate.transacting(trx);
    })
    .then(trx.commit)
    .catch(trx.rollback);
});
await sqlUpdateInsert;

第二次尝试 - 获取错误Transaction query already complete。这是基于使用 async/await 提交/回滚 knex 事务

await kx.transaction(async (trx) => {
  try {
    await sqlStageInsert.transacting(trx);
    await sqlTaskPcUpdate.transacting(trx);
    trx.commit();
  } catch (error) {
    trx.rollback();
    throw error;
  }
});
4

1 回答 1

1

我建议您先尝试在阶段表中插入数据,然后检索属于两个表的公共值,以便在更新任务表的类中应用(假设两个表都包含具有相同数据的任何一个公共列)。

请注意,根据 knexjs.org 网站,knex.transaction() 使用关于 PostgreSQL 的返回语句来插入/更新多个表以保持一致性,但是 MySQL 不支持事务,因为我正在使用返回值在下面的代码中。

FYR, http: //knexjs.org/#Transactions

请参考下面的代码片段供您参考:

db.transaction(trx => {
  trx.insert({
    officeid: 'OFF000',
    taskid: 'T002'
  })
  .into('stage')
  .then(() => {
    return trx('stage').where({taskid}).then(resp => resp[0].taskno)
  })
  .then(stageTaskno => {
    return trx('task')
          .update({pc: 100})
          .where({stageTaskno})
          .limit(1)
          .then(resp => {
            resp.json(resp)
          })
  })
  .then(trx.commit)
  .catch(trx.rollback)
});

希望这有帮助,干杯!

于 2019-09-21T18:18:50.120 回答