Нежелательное продвижение с использованием TransactionScope

#sql #wcf #transactionscope

#sql #wcf #transactionscope

Вопрос:

У меня есть система, написанная на C#.net 2.0, sql 2005, где бизнес-уровень и уровень доступа к данным уже созданы и используют транзакции MSDTC. Создание соединения и открытие, закрытие и т.д. записываются на уровне доступа к данным каждым методом.

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

Я хочу, чтобы каждая транзакция происходила в LTM и отмечала повышение в MSDTC.

Если я пишу с использованием TransactionScope на бизнес-уровне с вызовом нескольких методов DAC внутри, транзакция повышается до DTC. С новыми классами я могу справиться с этим, открывая и закрывая соединение на бизнес-уровне до начала области транзакции, но что я могу сделать для старых написанных классов. Есть ли в .Net 4.0 способ обрабатывать продвигаемую область транзакций? Я использую WCF для новых сервисов и .net 4.0 для новой системы.

Ответ №1:

Вновь открытое соединение по умолчанию присоединяется к текущей транзакции. Если транзакция выполняется более чем на одном соединении (ресурсе), она автоматически повышается до MSDTC. Вы можете заставить SQL connection не присоединяться к текущей транзакции, указав Enlist=false в строке подключения.

Если каждый старый класс использует свое собственное соединение, вам следует использовать MSDTC, потому что в противном случае несколько изменений данных, выполняемых вашей бизнес-логикой, не будут в одной транзакции. Пример:

 using (var scope = new TransactionScope())
{
    DalA.DoSomething();  
    DalB.DoSomething();
    scope.Complete();
}
  

И DalA, и DalB используют свое собственное соединение. Если вы используете Enlist=false , они не будут в транзакции, и если DalB.Сбой doSomething не приведет к откату DalA.doSomething.

Правильный подход — либо использовать MSDTC, либо переписать ваши старые классы для использования одного соединения. Локальная транзакция работает только на одном ресурсе (соединении).