2015-08-14 3 views
6

Я использую EF 6 с шаблоном UoW. У меня есть несколько контекстов, определенных в моем UoW, так как я использую данные из нескольких баз данных. Кажется, что все работает правильно, кроме функции CommitAsync, которую я определил. Вот код, у меня есть:Использование асинхронных изменений сохранения в Entity Framework с несколькими контекстами

public async Task CommitAsync() 
    { 
     try 
     { 
      using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) 
      { 
       if (_context1 != null) 
        await _context1.SaveChangesAsync(); 
       if (_context2 != null) 
        await _context2.SaveChangesAsync(); 

       scope.Complete(); 
      } 
     } 
     catch (DbEntityValidationException ex) 
     { 
      //.. 
     } 
    } 

Когда я запускаю этот спасительный изменения в обоих контекстах я получаю код:

Менеджер транзакций отключил поддержку удаленных/сетевых операций. (Исключение из HRESULT: 0x8004D024)

Ожидание _context2.SaveChangesAsync(); где происходит ошибка. Если я удалю TransactionScope из этой функции, код, похоже, будет работать без ошибок. Я не решаюсь удалить область для нескольких контекстов.

Только в случае, если это поможет, вот код, я использую, чтобы вызывать эту функцию:

 state.Name = "Texas"; 
     _uow.StateRepository.Update(state); 

     user.FirstName = "John"; 
     _uow.UserRepository.Update(user); 

     await _uow.CommitAsync(); 

Спасибо!

+1

Нет ничего плохого в коде, это конфиг на коробке с кодом msdtc, который отключил удаленные/сетевые транзакции. –

+0

Почему вы хотите использовать TransactionScope? Если сбой сохранения не удастся, он все равно будет отменен. Использование TransactionScope просто приводит к возможным взаимоблокировкам. –

+2

@JamieRees Я подозреваю, что OP хочет, чтобы оба обновления работали или оба потерпели неудачу, и избегали ситуации, когда один работал, но один из них не удался. –

ответ

2

Использование двух соединений в одной области требует MSDTC.

Вы можете включить MSDTC для решения этой проблемы. Но он не работает со многими решениями HA и работает медленно.

Единственный способ избежать использования MSDTC - использовать одно и то же соединение для всего, что должно быть выполнено. Поскольку вы используете несколько баз данных, которые сложнее, чем обычно. Вам нужно использовать SqlConnection.ChangeDatabase или выпустить соответствующий SQL для переключения между базами данных по тому же соединению. Соединение должно быть открытым.

В качестве альтернативы вы можете использовать три названия деталей для ссылок на объекты (например, DB1.dbo.MyTable).

Другого выхода нет. Либо MSDTC, либо совместное использование одного и того же соединения.

+0

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

+0

@AaronSanders, если вам нравится отлаживать непоследовательные данные ... Это произойдет. Таймаут может произойти в любое время. – usr

+0

@AaronSanders дополнительное чтение для вас «Проблема двух генералов». Это мысленный эксперимент, который описывает, как FRIGGIN жестко распределенных транзакций. – Aron

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