【问题标题】:knex.raw and trx.commit in knex.transactionsknex.transactions 中的 knex.raw 和 trx.commit
【发布时间】:2019-01-27 01:21:50
【问题描述】:

我刚接触 knex 并遇到了交易。我认为它很有用,因为它具有回滚功能。尝试使用它(见下面的代码)

await knex.transaction(trx => {
knex.raw(delete from myTable where "id" = 1 )
  .transacting(trx) 
  .then(trx.commit)
  .catch(trx.rollback) 
})

我只是想删除具有某个 id 的行而已。 工作正常,然后我尝试删除“trx.commit”。我原以为它不会应用查询,但确实如此。据我了解,如果不调用 trx.commit,查询将不会运行,也不会影响数据库。

我的理解错了吗?我是否在 knex.transactions 中不正确地使用了 knex.raw?我没有看到使用原始查询的事务示例。顺便说一句,我已连接到我的 localhost(postgresql) 中的数据库。

【问题讨论】:

  • 我还注意到,有时当您忘记返回承诺或致电.commit 时,它会正确提交。话虽这么说,knex.js 对未定义的行为和在版本之间破坏它是不好的。不要强调它所做的没有记录的事情 - 坚持使用有意义并匹配文档的模式。还要注意它们的非 semver 重大更改。

标签: javascript knex.js


【解决方案1】:

knex.js 有一个修改过的 promise 接口。

调用 .then 会触发查询实际触发(如果是第一个查询,则包括 BEGIN 事务)。请注意,在单个 knex 查询中,您不需要调用回滚,因为对数据库的单个查询应该是事务性的,并且如果遇到任何错误则中止/回滚。

根据您的使用情况(和文档),如果您删除 trx.commit,则根本不应该提交。我建议实际上向事务回调返回一个承诺 - 然后它将在承诺解决时自动提交,并在承诺失败时自动回滚。

在以下用法中,如果任一查询失败,它将自动回滚所有内容。

knex.transaction(trx => {
  return Promise.all([
     knex.raw(`update table x`).transacting(trx),
     knex.raw(`update table y`).transacting(trx)
    ]);
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-30
    • 1970-01-01
    • 2013-03-10
    • 2016-04-10
    相关资源
    最近更新 更多