In my current project, I am utilizing managed transactions. There is a specific scenario where I need to implement a single transaction and revert to a certain savepoint if it encounters an error, but still ensure that the changes are committed in the end.
For instance, I aim to create an Event
and execute an action
. In case the action
fails, I wish to undo any database modifications made during the action while retaining the Event
record and updating it with the outcome afterwards.
const transaction = await sequelize.transaction();
const event = await Event.create({ ... }, { transaction });
// Set a savepoint here
try {
const action = await runAction(transaction);
event.status = 'success';
event.action_id = action.id;
} catch (err) {
// Rollback changes since the savepoint
event.status = 'failure';
event.failure_message = err.message;
}
await event.save({ transaction });
await transaction.commit();
To achieve this functionality, my understanding leads me to believe that creating a new transaction within the existing one can act as a savepoint:
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();
Nevertheless, despite attempting this method, the operations conducted within runAction
using the transaction remain committed. Is there an alternative approach to resolve this issue?