dotnet / dotnet/SqlClient

SqlException within concurrent call to ExecuteReader returns bad connections to the pool

Open
#1,887 8 comments 0 reactions 1 assignee Claimed by @mdaigle View on GitHub
Dominant language
C#
Stars
989
Forks
340
Avg merge
4d 19h
Merged PRs (30d)
72

Description

Under certain conditions, it's possible for a call to ExecuteReader to return results and/or errors from another instance of SqlCommand. For context, we're seeing this bug when calling Dapper's Query method. The following conditions must be met for this bug to occur:

1. A connection is being used in a thread-unsafe way
2. The two threads using the connection must be calling `ExecuteReader`, and at least one of the commands must throw a SqlException
3. A third, unrelated thread, using its own isolated `SqlConnection`, should run its own query at roughly the same time

Under these conditions, the third thread mentioned above may receive the error or result set from one of the first two threads' queries.

The bug occurs much more often if `ExecuteReader(CommandBehavior.CloseConnection)` is used.

The bug does _not_ occur if:

1. Neither of the two threads throws an error
2. `ExecuteReaderAsync` is used instead

### To reproduce

See attached zip solution/project
[ConnectionPoolPoisoning.zip](https://github.com/dotnet/SqlClient/files/10411851/ConnectionPoolPoisoning.zip)

### Expected behavior
Errors coming from thread-unsafe usage of SqlConnection shouldn't cause errors in other, well-behaving parts of the application.

### Further technical details
Microsoft.Data.SqlClient version: 5.0.1
.NET target: .NET 6.0
SQL Server version: SQL Server Express, Azure SQL Managed Instance as well
Operating system: Windows 10

I was also able to reproduce this with System.Data.SqlClient.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.