Repository navigation
CSHARP-6257: Fix WithTransaction not retrying TransientTransactionError when MongoClientSettings is created with its constructor - #2144
Open
flibustier7seas wants to merge 1 commit into
Conversation
…or when MongoClientSettings is created with its constructor
sanych-sun
requested review from
sanych-sun
and removed request for
ajcvickers
October 9, 2026 16:15
Member
|
Thank you for your contribution! I'll make sure the changes will be included into the next release. |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes https://jira.mongodb.org/browse/CSHARP-6257
The
MongoClientSettingsconstructor sets the internalTimeouttoTimeout.InfiniteTimeSpan, whileMongoClientSettings.FromConnectionString/FromUrlleave itnull. Since CSHARP-5712 (3.7.0),TransactionExecutor.IsTimedOutcompares the elapsed time with that value as if it were a finite deadline of −1 ms. As a result,WithTransaction[Async]gives up after the firstTransientTransactionError, for example a write conflict. Since CSHARP-5869 (3.8.0) that error is also wrapped inTimeoutException. The same code retried on 3.5.2.The infinite constructor default, introduced in 3.5.0 by CSHARP-3549, has a wider effect as well: a client built with the constructor runs every operation in CSOT mode even though the application never set
timeoutMS, becauseIsRootContextTimeoutConfigured()istruefor every operation.The driver's own integration and spec tests did not catch this. They build clients through
FromConnectionString/FromUrl(DriverTestConfiguration), so they always ran withTimeout == nulland never exercised the constructor default.Fix
MongoClientSettingsconstructor,Timeoutnow defaults tonull(unset), the same asMongoUrlBuilderandFromUrl. A client built with the constructor now behaves as the CSOT spec requires whentimeoutMSis not set.TransactionExecutor.IsTimedOutnow treats an infinite timeout as "no deadline", the same wayOperationContext.RemainingTimeoutalready does. This covers an infinite timeout set explicitly, for example throughTransactionOptions.Note the behaviour change for applications that build
MongoClientSettingswith the constructor. Their retryable reads and writes go back to a single retry, and per-operation options such asFindOptions.MaxTimeare sent asmaxTimeMSagain. Both are the existing behaviour that the spec requires whentimeoutMSis not set.Behaviour by version
timeoutMSnot set, settings created withnew MongoClientSettings()withTransactionretries for up to 120 seconds, then rethrows the last error (Convenient Transactions API)TimeoutisInfiniteTimeSpan, so retries are unboundedTimeoutExceptionwrapping the error (3.7.0: rethrows the error, still after one attempt)Timeoutisnull: retries for up to 120 seconds, then rethrows the last errortimeoutMSnot set, settings created withFromConnectionString/FromUrltimeoutMSfinitewithTransactioncallTimeoutExceptionwrapping the last error (3.7.0: rethrows the last error)timeoutMSinfinite, set explicitly (internal API only until CSOT GA)TimeSpanspecial values keep their meaning (timeoutMS)TimeoutExceptionwrapping the error (3.7.0: rethrows the error)timeoutMSnot set, settings created withnew MongoClientSettings()FindOptions.MaxTimeis not sent asmaxTimeMSFindOptions.MaxTimeis sent asmaxTimeMSTesting
ClientSessionHandleTests.WithTransaction_callback_with_a_TransientTransactionError_and_infinite_timeout_should_be_retried, which covers the sync and async paths. The mocked clock moves past 120 seconds before the retry, so the test also fails if an infinite timeout falls back to the 120-second limit. It fails onmainwithTimeoutException.MongoClientSettingsTests.TestDefaultsnow asserts thatTimeoutisnull. Together with the existing_settings.Timeout.HasValuecheck inMongoClient.StartSession, this means a client built with the constructor no longer passes a timeout to its sessions' default transaction options.