Я пытаюсь вложить 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.
Любые идеи, как я заставил бы это работать, или если это - даже возможное использование Системы. Пространство имен транзакций?
Спасибо
Вам, вероятно, не понравится этот ответ, но ...
Голосование внутри вложенной области
Хотя вложенная область может присоединиться к внешней транзакции корневой области, вызывая Complete ] во вложенной области не влияет на корневую область. Только если все области от корневой области до последней вложенной области проголосуют за фиксацию транзакции, транзакция будет зафиксирована.
(Из Реализация неявной транзакции с использованием области действия )
Класс TransactionScope
, к сожалению, не предоставляет никакого механизма (о котором я знаю) для разделения единиц работы. Все или ничего. Вы можете предотвратить выполнение любой транзакции в определенной единице работы с помощью TransactionScopeOption.Suppress
, но, вероятно, это не то, что вам нужно, поскольку в этом случае вы потеряете атомарность всего, что находится внутри этот объем.
При использовании TransactionScope
существует только одна «внешняя» транзакция. Как только TransactionScope
удаляется или собирается без выполнения Complete
, вся внешняя транзакция откатывается; все, игра окончена.
Фактически, SQL Server вообще не поддерживает истинные вложенные транзакции, хотя возможно (хотя и не совсем интуитивно) для достижения того же конечного результата при соответствующем использовании SAVE TRAN
] заявления. Повторная реализация этой логики как хранимой процедуры (или нескольких из них) может быть вашим лучшим вариантом, если вам требуется именно это поведение.