TransactionScope и пул соединений
Я пытаюсь выяснить, есть ли у нас проблемы в нашем приложении с соединениями с базой данных, использующими неправильные IsolationLevels. Наше приложение представляет собой приложение базы данных.Net 3.5, использующее SQL Server 2005.
Я обнаружил, что IsolationLevel соединений не сбрасывается, когда они возвращаются в пул соединений (см. Здесь), и также был очень удивлен, прочитав в этом сообщении в блоге, что каждый новый созданный TransactionScope получает свой собственный назначенный ему пул соединений.
Обновления нашей базы данных (через наши бизнес-объекты) происходят в TransactionScope (новый создается для каждого обновления графа бизнес-объекта). Но наши выборки не используют явную транзакцию. Так что мне интересно, можем ли мы когда-нибудь попасть в ситуацию, когда наши операции извлечения (которые должны использовать IsolationLevel по умолчанию - Read Committed) будут повторно использовать соединение из пула, который использовался для обновления, и наследовать обновление IsolationLevel (RepeatableRead)? Или наши обновления гарантированно будут использовать другой пул соединений, если посмотреть, как они заключены в TransactionScope?
Заранее спасибо,
Грэхем
2 ответа
Это беспокоит!
В статье Билла Вогана, на которую вы ссылаетесь, говорится, что "... каждый TransactionScope получает свой собственный пул", но код в статье поддержки, на которую вы ссылаетесь, предполагает, что это не так, поскольку второй запуск NoTxScope()
получает соединение из пула, который использовал повышенный уровень изоляции.
Вы можете "форсировать" проблему, [я рисую код из первой ссылки]:
static void ForceReadCommitedScope()
{
TransactionOptions op = new TransactionOptions();
op.IsolationLevel = IsolationLevel.ReadCommitted;
using (TransactionScope tx = new TransactionScope(TransactionScopeOption.RequiresNew, op))
{
SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=master;Integrated Security=True;");
SqlCommand com = new SqlCommand("select transaction_isolation_level from sys.dm_exec_sessions where (session_id = @@SPID)", con);
con.Open();
short level = (short)com.ExecuteScalar();
Console.WriteLine("transaction_isolation_level : " + level.ToString());
con.Close();
tx.Complete();
}
}
или добавив "..;Pooling=False"
к вашей строке подключения.
В SQL Server 2014 уровень изоляции для пула соединений сбрасывается, когда соединение возвращается в пул. В более ранних версиях это не так.
Смотрите это сообщение на форуме:
Обновить
Это снова вернулось к предыдущему поведению в SQL 2014 CU6 и SQL 2014 SP1 CU1 с этим исправлением:
"Предположим, что вы используете класс TransactionScope в клиентском исходном коде SQL Server и не открываете явно соединение SQL Server в транзакции. Когда соединение SQL Server освобождается, уровень изоляции транзакции сбрасывается неправильно".