The connection pool calls sp_resetconnection before recycling a connection. Resetting the transaction isolation level is not in the list of things that sp_resetconnection does. That would explain why “serializable” leaks across pooled connections.
I guess you could start each query by making sure it’s at the right isolation level:
if not exists (
select *
from sys.dm_exec_sessions
where session_id = @@SPID
and transaction_isolation_level = 2
)
set transaction isolation level read committed
Another option: connections with a different connection string do not share a connection pool. So if you use another connection string for the “serializable” queries, they won’t share a pool with the “read committed” queries. An easy way to alter the connection string is to use a different login. You could also add a random option like Persist Security Info=False;
.
Finally, you could make sure every “serializable” query resets the isolation level before it returns. If a “serializable” query fails to complete, you could clear the connection pool to force the tainted connection out of the pool:
SqlConnection.ClearPool(yourSqlConnection);
This is potentially expensive, but failing queries are rare, so you should not have to call ClearPool()
often.