Не удается получить доступ к удаленному объекту. Торговая операция


Мы используем 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 4

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();
                }