【问题标题】:Is there a way in pg-promise to trigger an inner transaction that won't affect the outer transaction?pg-promise 中是否有办法触发不会影响外部事务的内部事务?
【发布时间】:2018-02-24 00:43:01
【问题描述】:

pg-promise 中,我需要触发一个内部事务,该事务可以在需要时回滚,不会导致调用事务在出错时回滚:

var db = pgp()(connection);
db.task( function (tk){
  tk.method(/* Logic used to decide if I need to continue */)
  .then( function(data){
    if (!data) return;
    tk.tx( function*(tx){
      // Somewhere in here I need to fire another transaction that I don't care if it fails
      // but I need things to roll back inside of it should it fail
      // without cause this tx to fail
    })
  })
})

到目前为止,我所做的一切都只是导致外部事务 (tx) 在内部事务失败时回滚,而不是内部事务回滚并且外部事务继续执行后面的逻辑。如果子事务失败,是否有可靠的方法来导致不会导致tx 回滚的内部事务?

另外:当我尝试使用 Bluebird Promise.some(tx1, tx2) 时,这也会失败,因为失败会导致 tx 回滚,而另一个 tx# 也会失败并回滚。

【问题讨论】:

    标签: node.js postgresql transactions pg-promise


    【解决方案1】:

    pg-promise 中的所有内容,顾名思义,都建立在 Promise 之上,包括事务逻辑,因此您正在寻找的答案纯粹与 Promise 相关:

    如果您不希望内部 Promise 的结果影响外部 Promise,您只需不将该内部 Promise 链接到父级,而是在本地处理/处理它。

    对于您的交易,这意味着不是这个:

    tk.tx(function * (t1) {
        return yield t1.tx(function * (t2))
           // chained inner transaction (savepoint)
        });
    }).then(data=>{}).catch(error=>{});
    

    你会这样做:

    tk.tx(function * (t1) {
        t1.tx(function * (t2))
            // unchained/localized inner transaction (savepoint)
        }).then(data=>{}).catch(error=>{});
    }).then(data=>{}).catch(error=>{});
    

    即您在本地处理内部事务的结果,而不将其链接到父级。

    【讨论】:

    • 我很好奇是不是因为我们被锁定在旧版本的 pg-promise 中。我会去查看 github 上的提交历史以及可能的解决方案。
    • @RobertMennell 可能是你在中间混合了 ES6 生成器,这些可能很棘手,很容易在你应该或不应该使用 yield 的地方犯错;)
    • 感谢您指出这一点!没想到这一点,但对后来我的每个人都有帮助
    猜你喜欢
    • 2021-10-15
    • 1970-01-01
    • 1970-01-01
    • 2014-07-17
    • 2017-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多