将事务处理为Express中间件

时间:2018-02-02 16:59:08

标签: node.js express transactions sequelize.js

我试图将Sequelize交易添加到我的Express应用中,但我没有成功。我在应用程序中使用了异步/等待,并且我已经使用' cls-hooked'创建了命名空间。按照Sequelize交易文档的说明打包。

Sequelize.useCLS(require('cls-hooked').createNamespace('db'));

我的中间件非常简单,看起来像这样

module.exports = () => (req, res, next) => sequelize.transaction(async () => next());

和app.js

app.use(sequelizeTransaction());
app.use('/api', apiRoutes);

我也试过直接在路线上使用中间件,但我得到与上面相同的结果

router.post('/', sequelizeTransaction(), async (req, res) => {
    await serviceThatDoesTwoDBOperations();
});

结果是我获得了事务,但只是在第一个数据库操作周围。之后的所有内容都会被忽略,并且回滚不会发生在错误上。我可能做了一些明显错误的事情,但我不能指责它。

1 个答案:

答案 0 :(得分:2)

我和你有同样的问题。这就是我的工作方式。出于某种原因,sequelize是在命名空间实际完成之前清除事务。

还要确保您使用的是节点> 8.5用于async_hooks。

export const transactionMiddleware = async (req, res, next) => {
  namespace.bindEmitter(req);
  namespace.bindEmitter(res);
  namespace.bind(next);
  namespace.run(async () => {
    const transaction = await sequelize.transaction();
    namespace.set('transaction', transaction);
    onFinished(res, (err) => {
      if (!err) {
        transaction.commit();
      } else {
        transaction.rollback();
      }
    });
    next();
  });
};

我希望这对你有用:)