Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js 7 how to use sequelize transaction with async / await?

Node.js 7 and up already support async/await syntax. How should I use async/await with sequelize transactions?

like image 877
qiushijie Avatar asked Mar 18 '17 04:03

qiushijie


People also ask

How do you use async await in Sequelize?

–> First, in your project folder “sequelize async/await”, create a new JavaScript file and name it db. js. –> Next, install the mysql2 package inside our project “sequelize async/await”, then import it into db. js.

Does node js support async await?

Node. js 7.6 has shipped with official support for async / await enabled by default and better performance on low-memory devices.


3 Answers

let transaction;    

try {
  // get transaction
  transaction = await sequelize.transaction();

  // step 1
  await Model.destroy({ where: {id}, transaction });

  // step 2
  await Model.create({}, { transaction });

  // step 3
  await Model.update({}, { where: { id }, transaction });

  // commit
  await transaction.commit();

} catch (err) {
  // Rollback transaction only if the transaction object is defined
  if (transaction) await transaction.rollback();
}
like image 69
user7403683 Avatar answered Oct 20 '22 07:10

user7403683


The accepted answer is an "unmanaged transaction", which requires you to call commit and rollback explicitly. For anyone who wants a "managed transaction", this is what it would look like:

try {
    // Result is whatever you returned inside the transaction
    let result = await sequelize.transaction( async (t) => {
        // step 1
        await Model.destroy({where: {id: id}, transaction: t});

        // step 2
        return await Model.create({}, {transaction: t});
    });

    // In this case, an instance of Model
    console.log(result);
} catch (err) {
    // Rollback transaction if any errors were encountered
    console.log(err);
}

To rollback, just throw an error inside the transaction function:

try {
    // Result is whatever you returned inside the transaction
    let result = await sequelize.transaction( async (t) => {
        // step 1
        await Model.destroy({where: {id:id}, transaction: t});

        // Cause rollback
        if( false ){
            throw new Error('Rollback initiated');
        }

        // step 2
        return await Model.create({}, {transaction: t});
    });

    // In this case, an instance of Model
    console.log(result);
} catch (err) {
    // Rollback transaction if any errors were encountered
    console.log(err);
}

If any code that throws an error inside the transaction block, the rollback is automatically triggered.

like image 40
kosinix Avatar answered Oct 20 '22 07:10

kosinix


The answer given by user7403683 describes async/await way for unmanaged transaction (http://docs.sequelizejs.com/manual/tutorial/transactions.html#unmanaged-transaction-then-callback-)

Managed transaction in async/await style may look as follows:

await sequelize.transaction( async t=>{
  const user = User.create( { name: "Alex", pwd: "2dwe3dcd" }, { transaction: t} )
  const group = Group.findOne( { name: "Admins", transaction: t} )
  // etc.
})

If error occurs, the transaction is automatically rolled back.

like image 7
rlib Avatar answered Oct 20 '22 09:10

rlib