续集expressjs中的事务未执行

Posted

技术标签:

【中文标题】续集expressjs中的事务未执行【英文标题】:sequelize transactions in expressjs not executing 【发布时间】:2018-11-29 22:41:57 【问题描述】:

试图找出在 expressjs 中使用 Sequelize 事务的正确方法。 以下代码通过 id 查找帖子,增加帖子表中的回复计数,更新帖子,然后在回复表中创建回复。尝试在控制器操作中调用代码但它不起作用。内部承诺没有受到打击。关于在 Sequelize 中使用交易的正确方法有什么建议吗?

Sequelize.transaction(function (t)   
db.Post.find(where:id: postId, transaction:t).then(function(post)

  var count = post.reply + 1; 
  post.update(replyCount:count,transaction:t);
  db.Reply.create(replyData, transaction:t).then(function(newcomment, created)      
          res.json(newcomment);

      );     
);
  ).then(function (result) 
// Transaction has been committed
// result is whatever the result of the promise chain returned to the transaction callback 
 ).catch(function (err) 
// Transaction has been rolled back
// err is whatever rejected the promise chain returned to the transaction 
);        
);

【问题讨论】:

【参考方案1】:
Sequelize.transaction(function (t)   
 return db.Post.find(where:id: postId, transaction:t).then(function(post)

  var count = post.reply + 1; 
  return post.update(replyCount:count,transaction:t)
         .success(result =>
              // i guess you want to use result in here to create replyData
              return db.Reply.create(replyData, transaction:t)

                     .then(function(newcomment, created)      
                           return res.json(newcomment);

                      ); 
         );

);

【讨论】:

这个答案确实解决了“使用 Sequelize 交易的正确方法”。它没有解决初始 .find() 查询不会改变数据库,因此在事务中没有任何价值的事实。请参阅下面的 ES6 解决方案,它使用 try/catch、等待和自动事务功能来解决问题。【参考方案2】:

交易中的初始 .find() 没有任何价值。在回滚的情况下没有什么可以撤消的。只有写入或更新需要在事务中回滚。 try/catch 将处理任何失败的查询,并为事务项自动触发回滚。

考虑这个更现代的 ES6 解决方案:

try 

  const result = await sequelize.transaction(async (t) => 

    // no need to include this in the transaction, it only reads (find)
    const post = await db.Post.find(where:id: postId);

    const count = post.reply + 1;
    const updateResult = await post.update(
      replyCount: count
    ,  transaction: t );

    // i guess you want to use result in here to create replyData
    const createResult = await db.Reply.create(
      replyData,
    ,  transaction:t );

    return res.json(newcomment);
  );

 catch (error) 

  // If the execution reaches this line, an error occurred.
  // The transaction has already been rolled back automatically by Sequelize!


参考: - https://sequelize.org/master/manual/transactions.html#managed-transactions

【讨论】:

以上是关于续集expressjs中的事务未执行的主要内容,如果未能解决你的问题,请参考以下文章

express js 中的 Socket.io:Router.use 需要中间件功能但未定义

ExpressJS - 抛出未处理的错误事件

如何正确处理 Express 中的错误?

如何在 Node.js expressjs 的异步对象方法中处理未处理的承诺拒绝?

如何在 expressjs 4.0 中设置 marko 模板引擎

学习使用ExpressJS 4.0中的新Router