Enable ConnectionPoolV2 by default - #4589
Open
mdaigle wants to merge 17 commits into
Open
Conversation
Flip the default value of the UseConnectionPoolV2 AppContext switch from false to true, making the new Channel-based connection pool (ChannelDbConnectionPool) the default implementation. The legacy V1 pool (WaitHandleDbConnectionPool) remains available by explicitly setting the switch to false. - Update XML doc comment on the switch to reflect the new default - Update features.instructions.md default value table - Update LocalAppContextSwitchesTest default-value assertion Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Task.Factory.StartNew with an async lambda returns Task<Task>. Without Unwrap(), Task.WhenAny observed only the outer task, which completed as soon as the async lambda hit its first await, rather than waiting for RunPacketNumberWraparound to actually finish. This masked itself under the legacy WaitHandleDbConnectionPool's synchronous-leaning timing, but was exposed by ChannelDbConnectionPool's genuinely asynchronous pooled open path, producing spurious low-enumerator-count failures. Also capture and await the winning task when it is actionTask so any unexpected failure (e.g. a connection open failure) propagates as a real exception instead of surfacing only as a generic count mismatch. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use unique pool-group keys for ephemeral simulated servers and isolate login-token handling from fatal connection-break behavior. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Observe asynchronous stress workers so connection failures fail the test instead of terminating the test host, and quarantine the sync variant of the known transient retry timing flake. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Count completed failover logins so abandoned pre-login transport attempts do not obscure the fresh physical connection created after the pool is cleared. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Enables ChannelDbConnectionPool (ConnectionPoolV2) as the default connection pooling implementation via LocalAppContextSwitches.UseConnectionPoolV2, updating documentation and tests to reflect the new default and to cover key behavioral/regression scenarios discovered during prior CI/perf validation.
Changes:
- Flip
UseConnectionPoolV2default totrueand update switch documentation + default-value unit test. - Add/adjust targeted tests covering (a)
Enlist=falsebehavior under an ambient transaction (sync + async), (b) “expired timeout prevents physical creation”, and (c) resiliency replacement when the old connection was already removed. - Fix
TvpTest.TestPacketNumberWraparoundto correctly unwrap/observe the nestedTask<Task>produced byTask.Factory.StartNew.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs | Sets UseConnectionPoolV2 default to true and updates its XML doc comment accordingly. |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs | Adjusts ReplaceConnection to reacquire via the normal path when the old connection is no longer in this pool. |
| src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/LocalAppContextSwitchesTest.cs | Updates the default-switch assertion to expect UseConnectionPoolV2 == true. |
| src/Microsoft.Data.SqlClient/tests/UnitTests/ConnectionPool/ChannelDbConnectionPoolTest.cs | Adds deterministic coverage ensuring expired timeouts prevent physical connection creation attempts. |
| src/Microsoft.Data.SqlClient/tests/UnitTests/ConnectionPool/ChannelDbConnectionPoolReplaceConnectionTest.cs | Adds coverage for replacement after the old connection has already been removed; adds a test helper method to doom stub connections. |
| src/Microsoft.Data.SqlClient/tests/UnitTests/SimulatedServerTests/ConnectionTests.cs | Adds an in-proc TDS server test verifying Enlist=false prevents ambient transaction enlistment for both Open and OpenAsync. |
| src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/TvpTest.cs | Fixes nested-task handling from Task.Factory.StartNew by unwrapping and explicitly observing failures. |
| src/Microsoft.Data.SqlClient/tests/FunctionalTests/AmbientTransactionFailureTest.cs | Removes the prior timing/ambient-transaction-based functional test (replaced by direct public-API coverage elsewhere in this PR). |
| .github/instructions/features.instructions.md | Updates the switch table to reflect UseConnectionPoolV2 defaulting to true and how to restore V1. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
paulmedynski
approved these changes
Aug 25, 2026
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.
Description
Changes the default connection pool from
WaitHandleDbConnectionPooltoChannelDbConnectionPool. Applications can restore the legacy pool explicitly:The full CI matrix exposed and this PR retains fixes for:
Task<Task>inTvpTest.TestPacketNumberWraparound.Enlist=falsepublic-API coverage.Flaky-test stabilization and quarantine changes discovered during investigation were removed for a separate PR. No public APIs change.
A best-of-three comparison covered 162 benchmarks with a 10% threshold. It found 41 improvements, 9 confirmed regressions, and 3 unconfirmed regressions. The strongest remaining regression signals are fixed overhead in pooled
OpenAsync, synchronization in rapid open/close loops, and contention whenMaxPoolSizeis small relative to concurrency.Issues
Supersedes #4537, which used a fork-backed branch.
The prerequisite emancipated connection reclamation fix merged through #4529.
Testing
ChannelDbConnectionPoolTest: 64/64 passed on net9.0 after rebasing ontomain.ChannelDbConnectionPoolReplaceConnectionTest: 16/16 passed on net8.0 and net9.0.Open_WithEnlistDisabled_DoesNotEnlistInAmbientTransaction: sync and async cases passed on net8.0 and net9.0.Guidelines
Please review the contribution guidelines before submitting a pull request: