Вложенный/Ребенок Откат TransactionScope

Я пытаюсь вложить TransactionScopes (.net 4.0), поскольку Вы вложили бы Транзакции в SQL Server, однако похоже, что они работают по-другому. Я хочу, чтобы мои дочерние транзакции смогли откатывать, если они перестали работать, но позволяют родительской транзакции решать, фиксировать ли/откатывать целую операцию. Проблема состоит в том, когда первое полное происходит, транзакция откатывается. Я понимаю, что завершенный отличается от фиксации.

Значительно упрощенный пример того, что я пытаюсь сделать:

static void Main(string[] args)
{
    using(var scope = new TransactionScope()) // Trn A
    {
        // Insert Data A

        DoWork(true);
        DoWork(false);

        // Rollback or Commit
    }
}

// This class is a few layers down
static void DoWork(bool fail)
{
    using(var scope = new TransactionScope()) // Trn B
    {
        // Update Data A

        if(!fail)
        {
            scope.Complete();
        }
    }
}

Я не могу использовать опции Suppress или RequiresNew, поскольку Trn B полагается на данные, вставленные Trn A. Если я действительно использую те опции, Trn B заблокирован Trn A.

Любые идеи, как я заставил бы это работать, или если это - даже возможное использование Системы. Пространство имен транзакций?

Спасибо

27
задан Robert Wagner 30 April 2010 в 02:36
поделиться

1 ответ

Вам, вероятно, не понравится этот ответ, но ...

Голосование внутри вложенной области

Хотя вложенная область может присоединиться к внешней транзакции корневой области, вызывая Complete ] во вложенной области не влияет на корневую область. Только если все области от корневой области до последней вложенной области проголосуют за фиксацию транзакции, транзакция будет зафиксирована.

(Из Реализация неявной транзакции с использованием области действия )

Класс TransactionScope , к сожалению, не предоставляет никакого механизма (о котором я знаю) для разделения единиц работы. Все или ничего. Вы можете предотвратить выполнение любой транзакции в определенной единице работы с помощью TransactionScopeOption.Suppress , но, вероятно, это не то, что вам нужно, поскольку в этом случае вы потеряете атомарность всего, что находится внутри этот объем.

При использовании TransactionScope существует только одна «внешняя» транзакция. Как только TransactionScope удаляется или собирается без выполнения Complete , вся внешняя транзакция откатывается; все, игра окончена.

Фактически, SQL Server вообще не поддерживает истинные вложенные транзакции, хотя возможно (хотя и не совсем интуитивно) для достижения того же конечного результата при соответствующем использовании SAVE TRAN ] заявления. Повторная реализация этой логики как хранимой процедуры (или нескольких из них) может быть вашим лучшим вариантом, если вам требуется именно это поведение.

48
ответ дан 28 November 2019 в 05:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: