Node.js 7 and up already support async/await syntax. How should I use async/await with sequelize transactions?
If CLS is enabled, Sequelize can use that to keep your transaction object and automatically pass it to all queries inside the continuation-passing
cycle.
Setup:
import { Sequelize } from "sequelize";
import { createNamespace } from "cls-hooked"; // npm i cls-hooked
const cls = createNamespace("transaction-namespace"); // any string
Sequelize.useCLS(cls);
const sequelize = new Sequelize(...);
Usage:
const removeUser = async (id) => {
await sequelize.transaction(async () => { // no need `async (tx)`
await removeClasses(id);
await User.destroy({ where: { id } }); // will auto receive `tx`
});
}
const removeClasses = async (userId) => {
await UserClass.destroy({ where: { userId } }); // also receive the same transaction object as this function was called inside `sequelize.transaction()`
await somethingElse(); // all queries inside this function also receive `tx`
}
How it works?
From Sequelize source code: github.com/sequelize
Check and save transaction to CLS
if (useCLS && this.sequelize.constructor._cls) {
this.sequelize.constructor._cls.set('transaction', this);
}
Retrieve transaction from CSL and set to options
if (options.transaction === undefined && Sequelize._cls) {
options.transaction = Sequelize._cls.get('transaction');
}
Read more: