在 Postgres 的 Sequelize 中使用事务

Using Transaction in Sequelize for Postgres

我正在尝试在 noodejs 中进行 sequelize 事务。我正在使用 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;
    })
}

使用Continuation Local Storage。这会将 global-level Sequelize 包分配给 "namespace",以便从中创建的所有实例在执行事务时都引用命名空间。

你初始化 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 的情况下执行交易。它还会回滚未捕获的异常(或技术上,未解决的承诺),并提交已解决的承诺:

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

它...

  • 开始事务(BEGIN; 在 PostgreSQL 中)
  • 创建一个新帐户(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 变量或显式 rollback/commit。