Для msdtc проблемы с транзакциями в лицо ADO.NET рамки
-
05-07-2019 - |
Вопрос
в нашем текущем проекте мы используем 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 не сможет подключиться к базе данных. Откройте и запустите координатор распределенных транзакций
Услуги - > Координатор распределенных транзакций