Transactions Node.js 7如何将sequelize事务与async/await一起使用?

Transactions Node.js 7如何将sequelize事务与async/await一起使用?,transactions,sequelize.js,Transactions,Sequelize.js,Node.js 7及以上版本已经支持异步/等待语法。如何在sequelize事务中使用async/await?let事务; 试一试{ //获取事务 事务=等待续集。事务(); //第一步 wait Model.destroy({where:{id},transaction}); //步骤2 wait Model.create({},{transaction}); //步骤3 wait Model.update({},{where:{id},transaction}); //承诺 等待事务。提交(

Node.js 7及以上版本已经支持异步/等待语法。如何在sequelize事务中使用async/await?

let事务;
试一试{
//获取事务
事务=等待续集。事务();
//第一步
wait Model.destroy({where:{id},transaction});
//步骤2
wait Model.create({},{transaction});
//步骤3
wait Model.update({},{where:{id},transaction});
//承诺
等待事务。提交();
}捕捉(错误){
//仅当定义了事务对象时才回滚事务
if(transaction)等待transaction.rollback();
}

上述代码在销毁调用中有错误

 await Model.destroy({where: {id}, transaction});

事务是选项对象的一部分。

用户7403683给出的答案描述了非托管事务的异步/等待方式()

异步/等待样式的托管事务可能如下所示:

await sequelize.transaction( async t=>{
  const user = User.create( { name: "Alex", pwd: "2dwe3dcd" }, { transaction: t} )
  const group = Group.findOne( { name: "Admins", transaction: t} )
  // etc.
})
如果发生错误,事务将自动回滚。

接受的答案是“非托管事务”,这要求您显式调用
commit
rollback
。对于任何想要“托管事务”的人来说,这就是它的样子:

试试看{
//结果是您在事务中返回的内容
让结果=等待续集。事务(异步(t)=>{
//第一步
wait Model.destroy({where:{id:id},transaction:t});
//步骤2
返回等待模型。创建({},{transaction:t});
});
//在本例中,模型的一个实例
控制台日志(结果);
}捕捉(错误){
//遇到任何错误时回滚事务
控制台日志(err);
}
要回滚,只需在事务函数中抛出一个错误:

试试看{
//结果是您在事务中返回的内容
让结果=等待续集。事务(异步(t)=>{
//第一步
wait Model.destroy({where:{id:id},transaction:t});
//导致回滚
if(false){
抛出新错误(“回滚已启动”);
}
//步骤2
返回等待模型。创建({},{transaction:t});
});
//在本例中,模型的一个实例
控制台日志(结果);
}捕捉(错误){
//遇到任何错误时回滚事务
控制台日志(err);
}

如果任何代码在事务块内抛出错误,则会自动触发回滚。

如果启用了CLS,Sequelize可以使用它保留事务对象,并自动将其传递给
继续传递循环内的所有查询

async () => {
  let t;

  try {
    t = await sequelize.transaction({ autocommit: true});

    let _user = await User.create({}, {t});

    let _userInfo = await UserInfo.create({}, {t});

    t.afterCommit((t) => {
      _user.setUserInfo(_userInfo);
      // other logic
    });
  } catch (err) {
    throw err;
  }
}
设置:

从“Sequelize”导入{Sequelize};
从“cls挂钩”导入{createNamespace};//连接的npm i cls
const cls=createNamespace(“事务命名空间”);//任何字符串
使用cls(cls);
const sequelize=新的sequelize(…);
用法:

const removeUser=async(id)=>{
等待sequelize.transaction(async()=>{//no-need`async(tx)`
等待RemoveUserClass(id);
等待用户。销毁({where:{id}});//将自动接收`tx`
});
}
const removeUserClasses=async(userId)=>{
await UserClass.destroy({where:{userId}}});//还接收与在`sequelize.transaction()中调用此函数相同的事务对象`
wait somethingElse();//此函数中的所有查询也会收到'tx'`
}
它是如何工作的?

来自Sequelize源代码:
github.com/Sequelize

if(使用cls&&this.sequelize.constructor.\u cls){
this.sequelize.constructor.\u cls.set('transaction',this);
}

if(options.transaction==undefined&&Sequelize.\u cls){
options.transaction=Sequelize._cls.get('transaction');
}
阅读更多信息:


  • 这不管用
    t
    在本例中是一个承诺,而不是事务对象。@Pier,wait等待sequelize.transaction(),然后获取它的结果。t不是承诺,它是承诺的结果。当我执行.findOne()命令时,我似乎无法等待工作。它与此一起工作吗?如果
    transaction=wait sequelize.transaction()失败?然后
    transaction.rollback()
    将抛出一个错误。我们是否需要检查catch块中的事务是否可以使用.rollback?在我的情况下,它不起作用,直到我将事务作为key:value传递。例如,在上面的解决方案中,{transaction:transaction}正在工作。我使用的是sequelize 5.19.2版,不需要尝试,非常感谢,我一直在寻找这个解决方案。没有意识到您可以等待
    sequelize.transaction
    @hellowill89-您可以查看给定函数的文档。如果它返回承诺,则可以使用wait。
    属性“transaction”在类型“typeof import(“/Users/mac/Projects/myinvoice be/node\u modules/sequelize/types/index”)”上不存在。你是说“交易”吗?ts(2551)
    我已经从“sequelize”导入sequelize我想这是一个很好的完整性回答,但我不知道为什么我希望间接地抛出一个错误来回滚,而不是显式地声明它。也许如果你做的次数足够多会更好,但我自己更喜欢显式版本。