I'm trying to add Sequelize transactions to my Express app, but I'm unsuccessful. I'm using async/await across the app, and I've created the namespace using the 'cls-hooked' package as instructed on the docs for Sequelize transactions.
Sequelize.useCLS(require('cls-hooked').createNamespace('db'));
My middleware is pretty simple and looks something like this
module.exports = () => (req, res, next) => sequelize.transaction(async () => next());
and in app.js
app.use(sequelizeTransaction());
app.use('/api', apiRoutes);
I've also tried using the middleware directly on routes, but I get the same result as above
router.post('/', sequelizeTransaction(), async (req, res) => {
await serviceThatDoesTwoDBOperations();
});
The result is that I get the transaction, but only around the first DB operation. Everything after that is ignored, and rollbacks aren't happening on errors. I'm probably doing something obviously wrong, but I can't put my finger on it.
I was having the same issue as you. This is how I made it work. For some reason sequelize was clearing the transaction on the namespace before it was actually completed.
Also make sure that you are using node > 8.5 for the 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();
});
};
I hope that works for you :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With