Что следует учитывать при использовании System.Transactions в моем проекте EF?
Фон
У меня есть приложение MVC и служба Windows, которые обращаются к той же библиотеке доступа к данным, которая использует EntityFramework. Служба Windows отслеживает определенную активность в нескольких таблицах и выполняет некоторые вычисления.
Мы используем проект DAL для нескольких сотен баз данных, генерируя строку соединения для контекста во время выполнения.
У нас есть ряд функций (как хранимых процедур, так и методов.NET, которые вызывают объекты EF), которые из-за объема данных, которые мы используем, ОЧЕНЬ интенсивно работают с дБ и могут блокировать друг друга.
Эта проблема
Служба Windows не так важна, что не может ждать. Если что-то должно быть заблокировано, служба Windows может. Ранее я обнаружил ряд вопросов, в которых говорилось, что System.Transactions
это путь при установке уровня изоляции транзакции READ UNCOMMITTED для минимизации блокировок.
Я попробовал это, и я могу неправильно понять, что происходит, поэтому мне нужно кое-что прояснить.
Метод в службе Windows имеет следующую структуру:
private bool _stopMe = false;
public void Update()
{
EntContext context = new EntContext();
do
{
var transactionOptions = new System.Transactions.TransactionOptions();
transactionOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted;
using (var transactionScope = new System.Transactions.TransactionScope( System.Transactions.TransactionScopeOption.Required, transactionOptions))
{
List<Ent1> myEnts = (from e....Complicated query here).ToList();
SomeCalculations(myEnts);
List<Ent2> myOtherEnts = (from e... Complicated query using entities from previous query here).ToList();
MakeSomeChanges(myOtherEnts);
context.SaveChanges();
}
Thread.Sleep(5000); //wait 5 seconds before allow do block to continue
}while (! _stopMe)
}
Когда я выполняю свой второй запрос, генерируется исключение:
The underlying provider failed on Open.
Network access for Distributed Transaction Manager (MSDTC) has been disabled. Please
enable DTC for network access in the security configuration for MSDTC using the
Component Services Administrative tool.
The transaction manager has disabled its support for remote/network
transactions. (Exception from HRESULT: 0x8004D024)
Я могу предположить, что я не должен вызывать более одного запроса в этом блоке? Первый запрос вернулся просто отлично. Это выполняется для одной базы данных за раз (на самом деле другие экземпляры выполняются в разных потоках, и ничто из этого потока не затрагивает другие).
У меня вопрос, это как это следует использовать или есть что-то еще, что я должен знать?
Примечание: это функция мониторинга, поэтому она должна запускаться повторно.
1 ответ
В своем коде вы используете объем транзакции. Похоже, что в первом запросе используется легкая транзакция в БД. Когда приходит второй запрос, область действия транзакции обновляет транзакцию до распределенной транзакции.
Распределенная транзакция использует MSDTC.
Вот где появляется ошибка, по умолчанию MSDTC не включен. Даже если он включен и запущен, его необходимо настроить, чтобы удаленный клиент мог создать распределенную транзакцию.