[JAVA-4684] Read operations in transactions are incorrectly retried Created: 22/Jul/22 Updated: 28/Oct/23 Resolved: 25/Jul/22 |
|
| Status: | Closed |
| Project: | Java Driver |
| Component/s: | Retryability, Transaction Management |
| Affects Version/s: | 4.4.0 |
| Fix Version/s: | 4.7.1 |
| Type: | Bug | Priority: | Minor - P4 |
| Reporter: | Vitalijs Levasins | Assignee: | Jeffrey Yemin |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | regression | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Attachments: |
|
||||||||||||
| Issue Links: |
|
||||||||||||
| Case: | (copied to CRM) | ||||||||||||
| Description |
SummaryThe issue occurs when the first transactional read operation, which should initiate a transaction, fails (for instance, due to reelection of primary node). Mongo Driver incorrectly retries the operation, which leads to an error 251 "NoSuchTransaction". The expected result as per the retryable reads specification is that the read operation is not retried when executed in a transaction. Note that even after the bug is fixed, the outcome will be largely the same: an exception will be thrown with the TransientTransactionError error label. However, it will be a less confusing exception, and there will no longer be a retry which is contrary to specification. If the application uses ClientSession.withTransaction, the whole transaction will be retried upon catching an exception with the TransientTransactionError error label. Please provide the version of the driver. If applicable, please provide the MongoDB server version and topology (standalone, replica set, or sharded cluster).org.mongodb:mongodb-driver-core:4.6.1 We are using a replica set, managed by Atlas. How to ReproduceRun a find() command inside a transactional context after a reelection of primary node (in fact any network-specific error will do). Example: First attempt:
Then a connection error followed by a retry (note the missing startTransaction flag):
Followed by a confusing error message (but note the correct error label):
|
| Comments |
| Comment by Githook User [ 25/Jul/22 ] |
|
Author: {'name': 'Jeff Yemin', 'email': 'jeff.yemin@mongodb.com', 'username': 'jyemin'}Message: Do not retry a read operation when in a transaction (#982) Fixes a regression introduced in 4.4.0 in scope of
|
| Comment by Githook User [ 25/Jul/22 ] |
|
Author: {'name': 'Jeff Yemin', 'email': 'jeff.yemin@mongodb.com', 'username': 'jyemin'}Message: Do not retry a read operation when in a transaction (#982) Fixes a regression introduced in 4.4.0 in scope of
|
| Comment by Jeffrey Yemin [ 22/Jul/22 ] |
|
Changing to Minor because after fixing the bug the outcome is mostly the same: an exception will be thrown with the TransientTransactionError error label. However, it will be a less confusing exception, and there will no longer be a retry which is contrary to specification. If the application uses ClientSession.withTransaction, the whole transaction will be retried upon catching an exception with the TransientTransactionError error label. Fix is in review. |
| Comment by Jeffrey Yemin [ 22/Jul/22 ] |
|
Hi vitalijs_levasins@epam.com, thanks for reporting this issue. According to this section of the retryable reads specification, the driver should not be retrying this operation at all. We will investigate to see why it appears to be retrying. |
| Comment by Vitalijs Levasins [ 22/Jul/22 ] |
|
Retry operation is performed in FindOperation class. See execute() method. The issue can be easily reproduced if execution is stopped just before running of createReadCommandAndExecute(). Introduce some network issue and continue the execution. After some time, execution will be retried - when you'll get to the breakpoint (second attempt of running createReadCommandAndExecute()), enable the networking. Now mongo driver is able to run the find() command, which will be executed without startTransaction flag.
|