Пул соединений вызывает sp_resetconnection перед перезапуском соединения. Сброс уровня изоляции транзакции не входит в список вещей , которые делает sp_resetconnection. Это объясняет, почему «сериализуемые» утечки проходят через пул соединений.
Я думаю, вы могли бы начать каждый запрос, убедившись, что он находится на правильном уровне изоляции :
if not exists (
select *
from sys.dm_exec_sessions
where session_id = @@SPID
and transaction_isolation_level = 2
)
set transaction isolation level read committed
Другой вариант: соединения с другой строкой соединения не разделяют пул соединений. Поэтому, если вы используете другую строку подключения для «сериализуемых» запросов, они не будут делить пул с запросами «прочитано зафиксировано». Простой способ изменить строку подключения - использовать другой логин. Вы также можете добавить случайную опцию, например Persist Security Info=False;
.
Наконец, вы можете убедиться, что каждый «сериализуемый» запрос сбрасывает уровень изоляции, прежде чем он вернется. Если не удается выполнить «сериализуемый» запрос, вы можете очистить пул соединений , чтобы принудительно удалить испорченное соединение из пула:
SqlConnection.ClearPool(yourSqlConnection);
Это потенциально дорого, но неудачные запросы редки, поэтому вам не нужно часто звонить ClearPool()
.