Node.js - 如何使用 Sequelize 交易

Posted

技术标签:

【中文标题】Node.js - 如何使用 Sequelize 交易【英文标题】:Node.js - How to use Sequelize transaction 【发布时间】:2020-03-05 19:31:26 【问题描述】:

我是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】:

使用事务将其传递给您希望成为事务一部分的每个查询,然后在完成时调用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);
);

异步/等待

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

【讨论】:

以上是关于Node.js - 如何使用 Sequelize 交易的主要内容,如果未能解决你的问题,请参考以下文章

Node.js:如何在 Sequelize 中使用 Postgres 存储过程?

如何使用 Sequelize 和 node.js 进行批量插入

Node.js / Sequelize.js / Express.js - 如何插入多对多关联? (同步/异步?)

如何在 Node.js 中使用 Sequelize 运行 AND 和 Or 运算符

如何在 node.js 中使用 sequelize-npm 实现与连接表的一对多关系

如何在 Sequelize 中创建一个表以使用 Node JS 存储在 Postgresql 中