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: Should reset $isNew during the retry #13698

Closed
2 tasks done
wongsean opened this issue Aug 3, 2023 · 0 comments · Fixed by #13726
Closed
2 tasks done

Connection#transaction: Should reset $isNew during the retry #13698

wongsean opened this issue Aug 3, 2023 · 0 comments · Fixed by #13726
Milestone

Comments

@wongsean
Copy link

wongsean commented Aug 3, 2023

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Mongoose version

7.4.1

Node.js version

16.18.1

MongoDB server version

4.2

Typescript version (if applicable)

4.7.3

Description

I'm encountering a similar issue as described in #8852, while using the mongoose built-in transaction wrapper Connection#transaction.

To simplify the problem, I've created the reproducible code below.

The problem arises when I attempt to save a new document within a transaction. If a TransientTransactionError occurs during the first try and triggers a retry, the doc's $isNew flag is not reset before the second attempt. Consequently, the subsequent save operation throws a DocumentNotFound error because it attempts to send an update operation behind the scenes instead of an insert.

Upon digging into the code, I discovered that the state reset, which should occur here, only takes place after two failed tries (in the case of a retry), and not before each retry attempt.

Steps to Reproduce

const doc = new Model({ a: "b" });

await connection.transaction(
  async (session) => {
    await doc.save({ session });
    throw new MongoServerError({
      errorLabels: ["TransientTransactionError"],
    });
  },
  { readPreference: "primary" }
);

Expected Behavior

I expected that the state should be reset before every retry attempt, which should prevent the DocumentNotFound error from occurring.

At the moment, my workaround is moving const doc = new Model({ a: "b" }); into the transaction block.

@vkarpov15 vkarpov15 added this to the 7.4.4 milestone Aug 6, 2023
vkarpov15 added a commit that referenced this issue Aug 13, 2023
fix(connection): reset document state in between transaction retries
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants