【问题标题】:Using Transaction in Sequelize for Postgres在 Sequelize 中为 Postgres 使用事务
【发布时间】:2016-04-21 18:00:11
【问题描述】:

我正在尝试在 noodejs 中进行续集交易。我使用 postgres 作为我的数据库。当我调用 testDel 时,事务会在 testDel 中自动提交。即使事务自动提交已经设置为 false。

如果我将变量 t 从 Db.transaction 传递给 testDel,那么它将等待手动提交/回滚。 我可以不将 t 传递给函数吗?它使编码变得非常复杂。

编码如下:

Db.transaction({autocommit: false}).then((t) => {
    args = {vcTitle: {$ilike: '%ulie%'}};
    let boDelete = true;
    testDelPost(t, args)
    .then(rersult =>{
        if(rersult){
            t.commit();
        }else{
            t.rollback();
        }
    })
});             

function testDel(args){
    //the result got deleted and auto committed after this destroy, it 
    //doesn't wait for the above transaction to decide the commit or rollback.
    //If I pass t, and set traction: t in the destroy, then it work as expected
    return Db.models.Post.destroy({where: args})
    .then(result =>{
        if(result > 0){
            return true;
        }else{
            return false;
        }
    })
    .error(status =>{
        return error;
    })
}

【问题讨论】:

    标签: postgresql transactions sequelize.js


    【解决方案1】:

    使用Continuation Local Storage。这会将全局级别的 Sequelize 包分配给“命名空间”,以便从它创建的所有实例在执行事务时都引用该命名空间。

    你初始化 Sequelize 如下(假设 ES6 导入语法):

    // Grab packages we need
    
    import Sequelize from 'sequelize';
    import Cls from 'continuation-local-storage';    
    
    // Assign namespace to database
    
    Sequelize.cls = Cls.createNamespace('db');
    

    这允许您在不明确传递t 的情况下执行事务。它还回滚未捕获的异常(或技术上,未解决的承诺),并提交已解决的承诺:

    以下是我在生产代码中使用的示例函数,它演示了实际的概念。

    它...

    • 启动事务(PostgreSQL 中的BEGIN;
    • 创建一个新帐户 (INSERT INTO "accounts"...)
    • 创建将帐户加入帐户类型的条目 (INSERT INTO "account_type_accounts"...)
    • 创建将用户链接到帐户 (INSERT INTO "users_accounts"...) 的条目
    • 仅在上述所有操作都成功时才执行插入 (COMMIT;)。如果没有,它会回滚 (ROLLBACK;)

    代码如下:

    createAccount (user, accountType, query = {}) {
      // Start transaction
      return this.db.connection.transaction(() => {
        // Create the new account
        return this.db.models.Account.create(query).then(account => {
          // Associate with user & account type
          return P.all([user.addAccount(account), accountType.addAccount(account)]).then(()=> {
            // Return account back up the promise chain
            return account;
          });
        });
      });
    }
    

    请注意缺少t 变量或显式回滚/提交。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-03
      • 2020-04-10
      • 2019-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-03
      • 1970-01-01
      相关资源
      最近更新 更多