[DRIVERS-2584] Infinite loop in generic transactional provider due to dup keys Created: 03/Mar/23 Updated: 12/Dec/23 |
|
| Status: | Implementing |
| Project: | Drivers |
| Component/s: | Transactions |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Raman Gupta | Assignee: | Dmitry Rybakov |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | alex+, james+, rachelle+ | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Driver Changes: | Needed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Quarter: | FY24Q4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Downstream Changes Summary: | Summary of necessary driver changes
Commits that describes docs changes |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Case: | (copied to CRM) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Engineering Lead: | |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Start date: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Driver Compliance: |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Description |
|
This is a follow-up to This can cause an infinite loop when implementing a generic transactional callback. Say my client code does something like this in pseudo-code: inTransaction 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 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? |
| Comments |
| Comment by Githook User [ 05/Dec/23 ] |
|
Author: {'name': 'Dmitry Rybakov', 'email': 'dmitry.rybakov@mongodb.com', 'username': 'comandeo'}Message: DRIVERS-2584 Errors handling in Convenient Transactions API (#1475) Co-authored-by: Andreas Braun <alcaeus@users.noreply.github.com> |
| Comment by Durran Jordan [ 31/Jul/23 ] |
|
Looks like the solution here is for the driver to apply some custom label in this case and then not to retry the transaction in that specific scenario. |
| Comment by Durran Jordan [ 11/Apr/23 ] |
|
chris.kelly@mongodb.com could the server add the proposed label to the error for any case where the driver must not retry the transaction? Maybe something like "NonRetryableTransactionError" or something similar? Or is the expectation here that the driver would apply the label in this specific case? |
| Comment by Chris Kelly [ 06/Mar/23 ] |
|
Thanks for the detailed report! I'll pass this along to the relevant team to look into this further. Christopher |