Вопрос

в нашем текущем проекте мы используем ADO.NET Entity Framework в качестве уровня данных для приложения.Есть некоторые задачи, которые требуют выполнения в транзакции, потому что в базе данных предстоит проделать большую работу.Я использую Транзакционный обзор чтобы окружить эти задачи.

using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
    // Do something...
    transactionScope.Complete();
}

Проблема в том, что как только я использую Транзакционный обзор возникает исключение:

Исключение System.Data.EntityException:При открытии произошел сбой базового поставщика.---> Система.Транзакции.Исключение TransactionManagerCommunicationException:Не удалось установить связь с базовым менеджером транзакций.---> Система.Среда выполнения.Службы взаимодействия.Исключение COMException (0x80004005):Ошибка HRESULT E_FAIL была возвращена в результате вызова COM-компонента.

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

Исключение System.Data.EntityException:При открытии произошел сбой базового поставщика.---> Система.Транзакции.Исключение TransactionManagerCommunicationException:Доступ к сети для диспетчера распределенных транзакций (MSDTC) был отключен.Пожалуйста, включите DTC для доступа к сети в конфигурации безопасности для MSDTC с помощью средства администрирования служб компонентов.

Как бы ни был настроен MSDTC, Транзакционный обзор приведет к ошибке.Кто-нибудь знает, что здесь происходит не так?

Это было полезно?

Решение 8

Хм, похоже, сработает, когда я изменяю TransactionScopeOption чтобы "Подавить":

using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Suppress))
{
    ...
}

Все знают почему?

Другие советы

По умолчанию у MSDTC отключен доступ к сети.Чтобы заставить его работать, вам следует перейти к

Панель Управления-> Административных Администрирование->Службы Компонентов->Компонент Сервисов->вычисляет->Мой компьютер->правый кнопкой мыши->Свойства->координатор распределенных транзакций->безопасность Конфигурация

и установите следующие флажки Сетевой DTC-доступ, Разрешить входящий, Разрешить Исходящий. Аутентификация должна быть выбрана в соответствии с вашей средой.Возможно, вы также захотите взглянуть на Расшифровка инструмент для отладки распределенных транзакций.Чтобы дать вам ярлык - возможно, вам потребуется внести изменения в свой реестр:

HKLM\Программное обеспечение\Политики\Microsoft\Windows NT PCRestrictRemoteClients=0 HKLM\Программное обеспечение\Политики\Microsoft\Windows NT PCEnableAuthEpResolution=1

чтобы привести все в порядок.

Да, он работает с использованием Supress, потому что вы приказываете ему подавлять или игнорировать внешнюю транзакцию и создавать новую локальную транзакцию. Поскольку транзакция является локальной, это не распределенная транзакция, поэтому она не использует MSDTC, но вам, вероятно, не следует использовать Suppress, а вместо этого следует использовать Required.

Это означает, что она подавляет любую Транзакцию, которая может быть действительна в данный момент при вводе вашего блока кода, поэтому любые обновления, сделанные вашим кодом, не будут откатываться, если внешняя " ambient " транзакция решает откат.

Это статья, которую мы использовали для решения нашей аналогичной проблемы:

Устранение неполадок, связанных с MSDTC р>

Это в основном дополнение к ответу Николая Р. . Он уже рассмотрел некоторые из предложений, перечисленных в статье.

Примечание. Эта статья является частью документации по Biztalk, но она может применяться ко всему, что использует MSDTC.

" Если вы используете Entity Framework с транзакциями, Entity Framework автоматически открывает и закрывает соединение с каждым вызовом базы данных. Поэтому при использовании транзакций вы пытаетесь распределить транзакцию по нескольким соединениям. Это повышается до MSDTC. & Quot;

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

Может быть, это ваш ответ: Ошибка MSSQL «Базовый поставщик не удалось открыть»

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

Вопрос, который вам нужно задать себе, заключается в следующем:Получаете ли вы доступ к более чем 1 надежному ресурсу в вашем TransactionScope?Я имею в виду, открываете ли вы соединения с более чем 1 ДБ?

Это важный вопрос, поскольку транзакция будет переведена в DTC, если вы получите доступ более чем к 1 ресурсу длительного пользования.

В транзакции задействованы по крайней мере два долговременных ресурса, поддерживающих однофазные уведомления.Например, подключение к одному соединению с не приводит к продвижению транзакции.Однако всякий раз, когда вы открываете второе подключение к базе данных, вызывающее включение базы данных, System.Инфраструктура транзакций обнаруживает, что это второй долговременный ресурс в транзакции, и увеличивает его до транзакции MSDTC. Источник: MSDN

Если это так, вы можете решить свою проблему, правильно вложив свои transactionscopes, например:

//Create rootScope
using(TransactionScope rootScope = new TransactionScope()) 
{ 
    using(TransactionScope scope2 = new 
    TransactionScope(TransactionScopeOption.Required)) 
    {
         //Do work on DB1
         ...

         //Complete this ambient transaction
         scope2.Complete();
    } 

    using(TransactionScope scope3 = new 
    TransactionScope(TransactionScopeOption.Required)) 
    {
         //Do work on DB2
         ...

         //Complete this ambient transaction
         scope3.Complete();
    } 

    //Complete rootScope
    //The whole transaction will only be committed if you call 
    //Complete on the rootScope
    rootScope.Complete();

}

Вы можете найти более подробную информацию о TransactionScopes, о том, как работает вложенность,...вкл . MSDN.

Я надеюсь, что этот ответ поможет людям в будущем.

Если служба координатора распределенных транзакций не запущена, платформа Entity не сможет подключиться к базе данных. Откройте и запустите координатор распределенных транзакций

Услуги - > Координатор распределенных транзакций

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top