简体   繁体   中英

Node.js - How to use Sequelize transaction

I am a beginner with sequelize and cannot get the transactions to work. Documentation is unclear and makes the following example not able to adapt to my requirements.

  return sequelize.transaction(t => {
  // chain all your queries here. make sure you return them.
  return User.create({
    firstName: 'Abraham',
    lastName: 'Lincoln'
  }, {transaction: t}).then(user => {
    return user.setShooter({
      firstName: 'John',
      lastName: 'Boothe'
    }, {transaction: t});
  });

}).then(result => {
  // Transaction has been committed
  // result is whatever the result of the promise chain returned to the transaction callback
}).catch(err => {
  // Transaction has been rolled back
  // err is whatever rejected the promise chain returned to the transaction callback
});

First I have to insert a tuple in 'Conto', then insert another tuple in 'Preferenze' and finally based on the 'tipo' attribute insert a tuple in 'ContoPersonale' or 'ContoAziendale'.

If only one of these queries fails, the transaction must make a total rollback, commit.

The queries are:

Conto.create({
        id: nextId(),
        mail: reg.email,
        password: reg.password,
        tipo: reg.tipo,
        telefono: reg.telefono,
        idTelegram: reg.telegram,
        saldo: saldoIniziale,
        iban: generaIBAN()
    })

Preferenze.create({
        refConto: 68541
    })

if (tipo == 0) {
        ContoPersonale.create({
        nomeint: reg.nome,
        cognomeint: reg.cognome,
        dataN: reg.datan,
        cf: reg.cf,
        refConto: nextId()
        }) 
        }
else if (tipo == 1) { 
        ContoAziendale.create({
        pIva: reg.piva,
        ragioneSociale: reg.ragsoc,
        refConto: nextId()
        })
        }

With a transaction you pass it to each query you want to be part of the transaction, and then call transaction.commit() when you finished, or transaction.rollback() to roll back all the changes. This can be done use thenables however it is clearer when using async/await .

Since none of your queries depend on each other you can also make them concurrently using Promise.all() .

thenables (with auto commit)

sequelize.transaction((transaction) => {
  // execute all queries, pass in transaction
  return Promise.all([
    Conto.create({
      id: nextId(),
      mail: reg.email,
      password: reg.password,
      tipo: reg.tipo,
      telefono: reg.telefono,
      idTelegram: reg.telegram,
      saldo: saldoIniziale,
      iban: generaIBAN()
    }, { transaction }),

    Preferenze.create({
      refConto: 68541
    }, { transaction }),

    // this query is determined by "tipo"
    tipo === 0
      ? ContoPersonale.create({
          nomeint: reg.nome,
          cognomeint: reg.cognome,
          dataN: reg.datan,
          cf: reg.cf,
          refConto: nextId()
        }, { transaction })
      : ContoAziendale.create({
          pIva: reg.piva,
          ragioneSociale: reg.ragsoc,
          refConto: nextId()
        }, { transaction })
  ]);

  // if we get here it will auto commit
  // if there is an error it with automatically roll back.

})
.then(() => {
  console.log('queries ran successfully');
})
.catch((err) => {
  console.log('queries failed', err);
});

async/await

let transaction;
try {
  // start a new transaction
  transaction = await sequelize.transaction();

  // run queries, pass in transaction
  await Promise.all([
    Conto.create({
      id: nextId(),
      mail: reg.email,
      password: reg.password,
      tipo: reg.tipo,
      telefono: reg.telefono,
      idTelegram: reg.telegram,
      saldo: saldoIniziale,
      iban: generaIBAN()
    }, { transaction }),

    Preferenze.create({
      refConto: 68541
    }, { transaction }),

    // this query is determined by "tipo"
    tipo === 0
      ? ContoPersonale.create({
          nomeint: reg.nome,
          cognomeint: reg.cognome,
          dataN: reg.datan,
          cf: reg.cf,
          refConto: nextId()
        }, { transaction })
      : ContoAziendale.create({
          pIva: reg.piva,
          ragioneSociale: reg.ragsoc,
          refConto: nextId()
        }, { transaction })
  ]);

  // if we get here they ran successfully, so...
  await transaction.commit();
} catch (err) {
  // if we got an error and we created the transaction, roll it back
  if (transaction) {
    await transaction.rollback();
  }
  console.log('Err', err);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM