Skip to content

Conversation

@mdaigle
Copy link
Contributor

@mdaigle mdaigle commented Nov 12, 2025

Description

When I originally implemented #3019, due to a misunderstanding about when connections are activated/deactivated, I added an extraneous call to DbConnectionInternal.DeactivateConnection as part of the PutObjectFromTransactedPool. Connections are always deactivated at the time they are returned to the pool via the ReturnInternalConnection method and do not need to be activated/deactivated as they move between the main pool and the transacted pool. The activate and deactivate methods modify a counter value that tracks the number of connections in active use. This extra deactivate led to active connection counts going negative.

However, removing this DeactivateConnection call is also not entirely correct. Part of the deactivation process is setting the "reset" flags via a call to the ResetConnection method. These flags determine the Status value sent to the server when a connection is recycled out of the pool. Connections that are placed in the transacted pool may use status RESETCONNECTIONSKIPTRAN if they are participating in a distributed transaction. This gives extra guarantees that the server will not reset the connection's transaction state. When moving a connection out of the transacted pool and back into the main pool, we no longer want the server to maintain the association to the transaction because the transaction has ended and we want to use the connection for general purpose commands. Therefore, we need to downgrade the connection's status value to RESETCONNECTION. This way, the next time the connection is used its association with the transaction will be removed.

To appropriately set the reset flags without impacting the active connection counter, I exposed the ResetConnection method as internal so that it can be called directly by the pool. All other actions taken in DeactivateConnection are safe to skip at this point.

I hope to clean up this flow as part of adding transaction support to the new pool implementation, but it's out of scope for this PR.

Issues

#3640

Testing

None of our tests cover metrics. Working on adding that as part of the new connection pool work.
In the meantime, this change will be verified manually.

Existing distributed transaction tests show that the reset flags are still reevaluated correctly.

Copilot AI review requested due to automatic review settings November 12, 2025 01:36
Copilot finished reviewing on behalf of mdaigle November 12, 2025 01:38
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes a bug where active connection counts were going negative due to an extraneous call to DeactivateConnection() when connections were moved from the transacted pool back to the main pool.

  • Removes duplicate connection deactivation in PutObjectFromTransactedPool
  • Connections are already deactivated when returned to the pool via ReturnInternalConnection
  • Moving between transacted and main pools doesn't require re-deactivation

@mdaigle mdaigle marked this pull request as ready for review November 12, 2025 23:04
@mdaigle mdaigle requested a review from a team as a code owner November 12, 2025 23:04
Copilot AI review requested due to automatic review settings November 12, 2025 23:04
Copilot finished reviewing on behalf of mdaigle November 12, 2025 23:06
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

paulmedynski
paulmedynski previously approved these changes Nov 13, 2025
@paulmedynski paulmedynski self-assigned this Nov 14, 2025
Copy link
Contributor

@benrr101 benrr101 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, probably pretty decent. Just want to see what's the best choice for whether to make it abstract or only defined on the SqlInternalConnectionTds

Copilot AI review requested due to automatic review settings November 14, 2025 19:47
Copilot finished reviewing on behalf of mdaigle November 14, 2025 19:50
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs:3395

  • The comment says "It is important to do this on activate" but this is misleading. The ResetConnection() method is actually called during deactivation (see InternalDeactivate() at line 1805) and when returning from the transacted pool, not during activation.

Consider updating the comment to accurately reflect when this is called:

// For implicit pooled connections, if connection reset behavior is specified, reset
// the database and language properties back to default. It is important to do this on
// deactivation so that the connection state is prepared for recycling.
            // For implicit pooled connections, if connection reset behavior is specified, reset
            // the database and language properties back to default. It is important to do this on
            // activate so that the dictionary is correct before SqlConnection obtains a clone.

benrr101
benrr101 previously approved these changes Nov 14, 2025
Copilot AI review requested due to automatic review settings November 14, 2025 22:24
Copilot finished reviewing on behalf of mdaigle November 14, 2025 22:25
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

@codecov
Copy link

codecov bot commented Nov 17, 2025

Codecov Report

❌ Patch coverage is 50.00000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 76.49%. Comparing base (ac757fa) to head (32bacec).
⚠️ Report is 8 commits behind head on main.

Files with missing lines Patch % Lines
.../Microsoft/Data/ProviderBase/DbConnectionClosed.cs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3758      +/-   ##
==========================================
+ Coverage   76.47%   76.49%   +0.01%     
==========================================
  Files         273      274       +1     
  Lines       44180    43378     -802     
==========================================
- Hits        33787    33180     -607     
+ Misses      10393    10198     -195     
Flag Coverage Δ
addons 90.82% <ø> (ø)
netcore 76.56% <50.00%> (+0.06%) ⬆️
netfx 76.05% <50.00%> (-0.26%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@mdaigle mdaigle added this to the 7.0.0-preview3 milestone Nov 17, 2025
Copy link
Contributor

@benrr101 benrr101 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚢

@mdaigle mdaigle merged commit 37dde3f into main Nov 18, 2025
509 checks passed
@mdaigle mdaigle deleted the dev/mdaigle/active-connection-count branch November 18, 2025 01:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants