Невозможно получить доступ к удаленному объекту. Сделка - PullRequest
4 голосов
/ 25 августа 2009

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

9 голосов
/ 28 августа 2009

Вы создаете scope2 без явного параметра TransactionScopeOption, который дает значение по умолчанию TransactionScopeOption.Required, см. Раздел Замечания в пределах TransactionScope Constructor

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

В вашем примере окружение TransactionScope действительно уже существует (scope1), следовательно, новый вложенный TransactionScope (scope2) с неявным параметром TransactionScopeOption.Required использует существующую транзакцию окружения, а не создает новую Сама сделка.

Однако неявная семантика транзакции scope2 все еще остается в силе, поэтому существующая окружающая транзакция, созданная scope1, прерывается, потому что вы не вызываете Complete в конце scope2

Если этот метод не вызывается, прерывается транзакция, потому что транзакция менеджер интерпретирует это как систему сбой или эквивалент исключения выброшено в рамках сделки

Конечно, проблема сразу исчезнет, ​​если вы удалите scope2 или измените его семантику на TransactionScopeOption.RequiresNew (что означает 'Для области всегда создается новая транзакция.' ), потому что существующий окружающий транзакция, созданная scope1, больше не будет затронута.

См. Реализация неявной транзакции с использованием объема транзакции для получения более подробной информации об этом.

0 голосов
/ 15 сентября 2009

Как насчет этого синтаксиса, он очень похож, Scope2 завершен и удален позже.

Я также периодически вижу ошибку "Не удалось получить доступ к удаленному объекту" Транзакция ". Может ли это быть потому, что я должен был создать оба из них с TransactionScopeOption.RequiresNew вместо TransactionScopeOption.Required?

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