This is a follow-up to SERVER-34059.
This can cause an infinite loop when implementing a generic transactional callback.
Say my client code does something like this in pseudo-code:
inTransaction
execute insert with duplicate key
catch exception, return something
The client has caught the error and returned something rather than re-throwing. However, the `inTransaction` implementation does not know that the transaction has been aborted due to SERVER-34059 (see also https://jira.mongodb.org/browse/DOCS-11493, and so attempts to commit.
The commit call now throws a `MongoCommandException` with error 251 (`NoSuchTransaction`). This exception also has the `TransientTransactionError` label. Therefore, per documentation (https://www.mongodb.com/docs/manual/core/transactions-in-applications/), the `inTransaction` implementation should retry the entire transaction.
The client code then attempts the same insert resulting in dup key again, and now we have an infinite loop.
I understand that technical issues prevent the server from not aborting the transaction on the dup key error. However, the inTransaction implementation needs some way to differentiate this case from other transient errors, allowing it to ignore the error at commit time instead of retrying. We could ignore all NoSuchTransaction errors at commit time, but that feels like it may cause other unexpected issues.
Perhaps the error could carry an additional label? Something like "TransactionAbortedDueToDupKey" or maybe "TransactionAbortedDueToFailingOperation" or something like that?
- is depended on by
-
NODE-5659 Driver retries a transaction operation when a DuplicateKeyError is hit
- Blocked
- split to
-
CDRIVER-4755 Infinite loop in generic transactional provider due to dup keys
- Closed
-
CSHARP-4828 Infinite loop in generic transactional provider due to dup keys
- Closed
-
CXX-2778 Infinite loop in generic transactional provider due to dup keys
- Closed
-
GODRIVER-3033 Infinite loop in generic transactional provider due to dup keys
- Closed
-
NODE-5721 Infinite loop in generic transactional provider due to dup keys
- Closed
-
RUBY-3341 Infinite loop in generic transactional provider due to dup keys
- Closed
-
RUST-1788 Infinite loop in generic transactional provider due to dup keys
- Closed
-
MOTOR-1203 Infinite loop in generic transactional provider due to dup keys
- Backlog
-
PHPLIB-1298 Infinite loop in generic transactional provider due to dup keys
- Backlog
-
PYTHON-4019 Infinite loop in generic transactional provider due to dup keys
- Backlog
-
JAVA-5227 Update documentation for ClientSession#withTransaction
- Backlog