2016-11-21 4 views
0

Я использую TransactionScope, чтобы сделать метод, который содержит несколько транзакций sql транзакций. Теперь я должен назвать второй метод, который также использует ту же самую связь, и я получаю следующее исключение при connection.Open():Вызов транзакции и метода, который использует то же соединение

Сетевой доступ к распределенным Transaction Manager (MSDTC) был отключен. Включите DTC для доступа к сети в конфигурации безопасности для MSDTC с помощью инструмента администрирования служб компонентов .

Так что это псевдо-код:

public static void Method1() 
{ 
    using (TransactionScope scope = new TransactionScope()) 
    { 
     bool success = true; // will be set to false in an omitted catch 
     using (var connection = new SqlConnection(ConnectionString1)) 
     { 
      // ... 
      if(somethingHappened) 
       Method2(); 
     } 
     if(success) 
      scope.Complete(); 
    } 
} 

public static void Method2() 
{ 
    using (var connection = new SqlConnection(ConnectionString1)) 
    { 
     connection.Open(); // BOOOM! 
     // ... 
    } 
} 

Как избежать этого исключения без повторения кода из Method2 в Method1?

+1

Я получил это тоже, но на разных ConnectionStrings. – Steve

+0

http://stackoverflow.com/questions/7694/how-do-i-enable-msdtc-on-sql-server, проверьте, помогает ли ответ с 64 upvotes – mybirthname

+0

@Steve, эта ошибка при разных типах подключений ожидается поведение – Fabio

ответ

2

Если открыто более одного соединения под тем же TransactionScope, оно автоматически перейдет в код DTC.

Перед тем, как позвонить по телефону Method2, необходимо закрыть первое соединение.

public static void Method1() 
{ 
    using (TransactionScope scope = new TransactionScope()) 
    { 
     bool success = true; // will be set to false in an omitted catch 

     bool isSomethingHappened 
     using (var connection = new SqlConnection(ConnectionString1)) 
     { 
      isSomethingHappened = // Execute query 1 
     } 

     if(somethingHappened) 
      Method2(); 

     if(success) 
      scope.Complete(); 
    } 
} 
+0

Ах. Вопрос был о том же соединении * string *, а не о том же соединении: / – mayu

0

Я не знаю точного ответа, но я сделал бы соединение членом и слежу, если он открыт.

Тогда в Method1 и Method2 я получил бы соединение через какой-то GetConnection(), который открыл бы соединение при первом использовании.


После прочтения комментариев я бы предложил частный DoMethod2, который принимает объект соединения.

2

Вложенные соединения в рамках одной и той же области транзакций будут способствовать распределенной транзакции.

От SQL Server 2008 и выше нескольких (не вложенных) подключений под одной и той же областью транзакций не будет распространяться на распределенную транзакцию.

см this вопрос для получения дополнительной информации

 Смежные вопросы

  • Нет связанных вопросов^_^