【问题标题】:Sequelize Transaction Rollback to Specific SavepointSequelize 事务回滚到特定的保存点
【发布时间】:2020-09-14 19:24:07
【问题描述】:

我在我的项目中使用managed transactions,我有一个案例,我想使用单个事务并在失败时回滚到特定的保存点,但最后总是提交。

例如,我想创建一个Event 并尝试运行一个action。如果action 失败,我想回滚操作期间发生的任何数据库活动,但保留Event 记录并随后用结果更新它。

const transaction = await sequelize.transaction();

const event = await Event.create({ ... }, { transaction });

// I want to mark the savepoint here

try {
  const action = await runAction(transaction);
  event.status = 'success';
  event.action_id = action.id;
} catch (err) {
  // This is where I want to rollback any changes since the savepoint
  event.status = 'failure';
  event.failure_message = err.message;
}

await event.save({ transaction });
await transaction.commit();

据我了解,我应该能够通过使用现有交易创建一个新交易来实现这一点,有效地标记一个保存点:

const transaction = await sequelize.transaction();

const event = await Event.create({ ... }, { transaction });

const savepoint = await sequelize.transaction({ transaction });

try {
  const action = await runAction(savepoint);
  ...
} catch (err) {
  await savepoint.rollback();
  ...
}

await event.save({ transaction });
await transaction.commit();

但是这不起作用,并且在runAction 中使用事务的所有操作仍然被提交。有什么方法可以实现吗?

【问题讨论】:

    标签: javascript transactions sequelize.js


    【解决方案1】:

    我意识到我在runAction 中调用了一个findOrCreate。当在选项中提供事务时,Sequelize 在 findOrCreate 中创建保存点。

    在创建新事务并在选项中提供事务时,它会自动创建一个保存点as shown here。这个保存点被赋予一个 id(它基于父节点上新保存点的索引),并执行一个 db 查询来设置事务中的保存点。因此,当我运行sequelize.transaction({ transaction }); 时,它创建了一个名为“transaction-id-1”的保存点。稍后当调用 findOrCreate 并提供“保存点”事务时,它会创建一个同名的保存点“transaction-id-1”,从而有效地覆盖之前的保存点。

    所以我应该将父事务传递给 runAction 而不是 savepoint

    const transaction = await sequelize.transaction();
    
    const event = await Event.create({ ... }, { transaction });
    
    const savepoint = await sequelize.transaction({ transaction });
    
    try {
      // Pass parent transaction, rather savepoint transaction
      const action = await runAction(transaction);
      ...
    } catch (err) {
      await savepoint.rollback();
      ...
    }
    
    await event.save({ transaction });
    await transaction.commit();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-19
      • 1970-01-01
      • 2013-12-10
      • 1970-01-01
      • 1970-01-01
      • 2020-02-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多