Не удается получить доступ к удаленному объекту. Торговая операция
Мы используем Entity Framework и запускаем модульные тесты в области транзакций. Мы изначально получили ошибку в названии.
Мне удалось выделить проблему кое-что.
using (TransactionScope scope1 = new TransactionScope())
{
using (TransactionScope scope2 = new TransactionScope())
{
// Here there is no code
}
using (Entities se = new Entities())
{
EntityConnection entityConnection = (EntityConnection)se.Connection;
DbConnection storeConnection = entityConnection.StoreConnection;
storeConnection.Open(); // On this line the error occurs
// Some code that runs a stored procedure
}
}
Ошибка, которую мы получаем в данный момент, такова: "операция недопустима для состояния транзакции.."
Если я удаляю транзакцию scope2, все работает нормально.
Если я помечаю область 2 как внешнюю транзакцию, она также работает нормально.
2 ответа:
Вы создаете scope2 без явного параметра
TransactionScopeOption, который дает значение по умолчаниюTransactionScopeOption.Required, см. раздел Примечания внутриTransactionScope ConstructorЭтот конструктор создает новый область действия транзакции с транзакцией параметр scope равен требуемому. Этот означает, что требуется транзакция новые области применения и окружающей среды транзакция используется, если она уже есть существует. В противном случае он создает новый транзакция перед входом в систему масштаб.
В вашем примере окружающий
TransactionScopeдействительно уже существует (scope1), следовательно, новый вложенныйTransactionScope(scope2) с помощью неявного параметраTransactionScopeOption.Requiredиспользуется существующая внешняя транзакция, а не сама новая транзакция.Однако неявная транзакционная семантика
scope2все еще существует, следовательно, существующая внешняя транзакция, созданнаяscope1, прерывается, потому что вы не вызываетеCompleteв конце концов ...scope2:Неспособность вызвать этот метод прерывает сделки, поскольку сделка менеджер интерпретирует это как систему отказ или эквивалент исключения брошенный в рамках сделки
Конечно, проблема сразу же решается, если удалить
Подробнее об этом см. В разделе реализация неявной транзакции с использованием области действия транзакции.scope2или изменить его семантику наTransactionScopeOption.RequiresNew(Что означает 'для области всегда создается новая транзакция.'), поскольку существующая внешняя транзакция, созданнаяscope1, не будет пострадал больше.
Как насчет этого синтаксиса, это довольно похоже, Scope2 завершается и удаляется позже.
Я также периодически вижу ошибку "не удается получить доступ к удаленному объекту "транзакция". Может быть, потому, что я должен был создать оба из них с TransactionScopeOption.RequiresNew вместо TransactionScopeOption.Требуется?
TransactionOptions rootOptions = new TransactionOptions(); rootOptions.IsolationLevel = IsolationLevel.ReadCommitted; OtherObject.Scope2 = new TransactionScope(TransactionScopeOption.Required, rootOptions); TransactionOptions options = new TransactionOptions(); options.IsolationLevel = IsolationLevel.ReadCommitted; options.Timeout = getTransactionTimeout(); using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, options)) { ............. scope.Complete(); }