Node.js - Как использовать транзакцию Sequelize - PullRequest
0 голосов
/ 09 ноября 2019

Я новичок с sequelize и не могу заставить транзакции работать. Документация неясна и делает следующий пример неспособным адаптироваться к моим требованиям.

  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
});

Сначала мне нужно вставить кортеж в «Conto», затем вставить другой кортеж в «Preferenze» и, наконец, на основе атрибута «tipo» вставить кортеж в «ContoPersonale» или «ContoAziendale».

Если сбой только одного из этих запросов, транзакция должна выполнить полный откат, зафиксировать.

Запросы:

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()
        })
        }

1 Ответ

0 голосов
/ 11 ноября 2019

С транзакцией вы передаете ее каждому запросу, который хотите быть частью транзакции, а затем вызываете transaction.commit() по завершении или transaction.rollback(), чтобы откатить все изменения. Это можно сделать, используя thenables , однако это более понятно при использовании async/await.

Поскольку ни один из ваших запросов не зависит друг от друга, вы также можете сделать их одновременно, используя Promise.all().

thenables (с автоматической фиксацией)

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);
}
...