Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connection.transaction: Model instance state is not reverted after a failed transaction #8380

Closed
juona opened this issue Nov 25, 2019 · 3 comments
Labels
enhancement This issue is a user-facing general improvement that doesn't fix a bug or add a new feature
Milestone

Comments

@juona
Copy link

juona commented Nov 25, 2019

Do you want to request a feature or report a bug?

Something in between, probably more of a feature since it could be a large task.

What is the current behavior?

Model instance state is not reverted after a failed transaction and trying to save it after the transaction is aborted will result in a VersionError.

If the current behavior is a bug, please provide the steps to reproduce.

This is a pseudo example, not a real-world scenario. It's enough to reproduce the problem.

const session = await mongoose.startSession();
const user = await UserModel.findById(userId).session(session);

// Simulating a failed transaction
try {
  await session.withTransaction(async () => {
    user.name = "Updated name";
    await user.save();
    throw new Error("Fail the transaction");
  });
} catch (err) {
  logger.debug("Oops, transaction failed, updating user status...");
  user.status = "NAME_UPDATE_FAILED";
  // At this point user.name has not been reverted to what it was initially.
  // Furthermore, the version index user.__v will point to a non-existent document
  await user.save(); // This fails with a VersionError
}

If after the transaction fails I reset user.name and user.__v to their initial values, the catch statement executes correctly.

What is the expected behavior?

Model instance data is reverted to what it was initially if the related transaction fails.

What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.

I use mongoose 5.6.9 and for the time being I'd like to avoid the update to 5.7.12 'cause my env is quite unstable. I checked the release notes and open issues and have not noticed this behavour mentioned anywhere.

@juona
Copy link
Author

juona commented Nov 25, 2019

I can appreciate the potential difficulties in dealing with this, so no easy fix expected. Perhaps a compromise solution could be implemented, e.g. automatically managing only the internal fields such as __v, etc. In case this is (for the time being?) too difficult to fix, some documentation would be nice. I could then infer from it what exact actions I have to take after my transaction fails, in order to fully and correctly reset my model instance state. Happy to hear your thoughts!

@ghost
Copy link

ghost commented Dec 2, 2019

shouldn't you use session.abortTransaction()?

@juona
Copy link
Author

juona commented Dec 3, 2019

The withTransaction helper deals with that, AFAIK. If there's an error, it aborts the transaction.

@vkarpov15 vkarpov15 added this to the 6.0 milestone Dec 7, 2019
@vkarpov15 vkarpov15 added the enhancement This issue is a user-facing general improvement that doesn't fix a bug or add a new feature label Dec 7, 2019
@vkarpov15 vkarpov15 modified the milestones: 6.0, 5.10 May 17, 2020
@vkarpov15 vkarpov15 changed the title Model instance state is not reverted after a failed transaction Connection.transaction: Model instance state is not reverted after a failed transaction Aug 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement This issue is a user-facing general improvement that doesn't fix a bug or add a new feature
Projects
None yet
Development

No branches or pull requests

3 participants