Notice how the callback passed to transaction returns a promise chain, and does not explicitly call t.commit() nor t.rollback(). If all promises in the returned chain are resolved successfully the transaction is committed. If one or several of the promises are rejected, the transaction is rolled back.

    When using the managed transaction you should never commit or rollback the transaction manually. If all queries are successful, but you still want to rollback the transaction (for example because of a validation failure) you should throw an error to break and reject the chain:

    1. return sequelize.transaction(t => {
    2. return User.create({
    3. firstName: 'Abraham',
    4. }, {transaction: t}).then(user => {
    5. throw new Error();
    6. });
    7. });

    Automatically pass transactions to all queries

    To enable CLS you must tell sequelize which namespace to use by using a static method of the sequelize constructor:

    1. Sequelize.useCLS(namespace);
    2. new Sequelize(....);

    Notice, that the useCLS() method is on the constructor, not on an instance of sequelize. This means that all instances will share the same namespace, and that CLS is all-or-nothing - you cannot enable it only for some instances.

    In most case you won't need to access namespace.get('transaction') directly, since all queries will automatically look for a transaction on the namespace:

    1. sequelize.transaction((t1) => {
    2. // With CLS enabled, the user will be created inside the transaction
    3. });

    After you've used all promises returned from sequelize will be patched to maintain CLS context. CLS is a complicated subject - more details in the docs for cls-bluebird, the patch used to make bluebird promises work with CLS.