2008-12-04 2 views
0

Я пытаюсь использовать System.Transaction.TransactionScope для создания транзакции для вызова нескольких хранимых процедур, но, похоже, не очищается после себя. Как только транзакция завершена (завершена или нет, и объект области транзакции будет удален), последующие соединения с базой данных будут открываться с уровнем фиксации чтения сериализуемым, а не читать, как обычно.System.Transaction неявная транзакция с другими моими подключениями

Я открываю и закрываю соединение для каждого вызова (хорошо закрывая и возвращаясь к пулу подключений, как обычно в .NET), я пропустил какой-то способ явно сбросить соединение, когда я закончил использовать его для транзакция? Я думал, что идея System.Transaction.TransactionScope заключалась в том, чтобы скрыть всю сложность.

Так код у меня выглядит следующим образом:

  using (var scope = new TransactionScope()) 
      { 
       ... make my 3 stored procedure calls ... 

       scope.Complete(); 

       return returnCode; 
      } 

, который я предполагаю, что это нормальный способ сделать это. Но если я смотрю в SQLServer профайлер я могу видеть соединения открываются с

set transaction isolation level serializable 

который баловаться с последующей активности базы данных без операций, связанных, а также, по-видимому, не так быстро. Я могу обойти это, установив опцию транзакции для объяснения транзакции с ReadCommited, но это не идеальное поведение для этой операции, на мой взгляд.

Я также попытался явно создать объект Commitabletransaction, создав эксплицитные новые транзакции вместо использования эмбиента, и до сих пор не повезло.

Любые идеи о том, как исправить это, будут высоко оценены, так как любые вызовы, которые используют сериализуемое соединение, будут вызывать ошибку, если они попытаются использовать подсказку readpast lock.

ответ

0

Вы также должны увидеть сброс (sp_reset_connection) между использованием одного и того же соединения в пуле; это не приведет к сбросу уровня изоляции? Вы пробовали воспроизвести сериализуемая проблему (например, блокировка эскалации ТУПИКИ)

+0

Я определенно вижу связи sp_reset.Я могу пройти и увидеть, что каждое соединение явно закрыто. Как вы относитесь к воспроизведению проблемы сериализации? Я использую систему только тогда, когда пытаюсь это сделать, и у меня нет никаких взаимоблокировок (проверка трассировки на профилировщике и протоколе транзакций). – mjallday

+0

Я имею в виду: вы утверждаете, что это мешает «последующей деятельности, связанной с транзакциями, связанной с базой данных», ; Я говорю: «ты уверен?». Я подозреваю, что sp_reset_connection означает, что последующая активность db не зависит от этого уровня изоляции. –

+0

Чтобы убедиться в этом, вам нужно будет проверить, выполнены ли дополнительные блокировки. Одним из вариантов является сценарий эскалации блокировки - то есть spid A считывает строку (без UPDLOCK), spid B считывает строку, A пытается обновить строку, B пытается обновить строку. Если эти взаимоблокировки, штифты являются сериализуемыми. –

1

Использование TransactionOptions.IsolationLevel

По default, it's serializable

TransactionOptions transactionoptions1 = new TransactionOptions(); 
transactionoptions1.IsolationLevel = IsolationLevel.ReadCommitted; 
using (var scope = new TransactionScope(TransactionScopeOption.Required, transactionoptions1)) 
{ 
    ... make my 3 stored procedure calls ... 

    scope.Complete(); 

    return returnCode; 
} 
+0

Это текущее решение, которое я использовал для решения этой проблемы. Но меня интересует, почему я вижу поведение, которое я вижу. Разумеется, последующие вызовы db не должны использовать уровень изоляции транзакции независимо? – mjallday

0

Это известное дизайнерское решение в SQL Server.

Также using new TransactionScope() Considered Harmful (06/2010, избегать конструктор по умолчанию)