Это шаблон, который я успешно использовал несколько раз:
Имеет объект «Менеджер транзакций», который внутренне отслеживает текущее соединение и транзакцию.Это может быть простая статика, для однопоточного приложения, или делать забавные вещи с локальным хранилищем потоков или даже с контекстом операций WCF.Идея состоит в том, что он дает вам единственное место для создания соединений и транзакций, которое отделено от кода, вызывающего базу данных.
Менеджер транзакций предоставляет открытый метод BeginTransaction, который возвращает объект транзакции, реализующий IDisposable.Каждый раз, когда вы вызываете BeginTransaction, вы получаете новый экземпляр области транзакции.
Объект области транзакции также предоставляет методы для получения соединения с базой данных и метод Commit, который должен быть вызван перед удалением.Если Commit не вызывается, транзакция будет откатываться на Dispose.
void M1()
{
using( var scope = TransactionManager.BeginTransaction() )
{
// Do stuff with the database.
M2(); // M2 and M3 each create their own scopes that share the transaction
M3(); // created by M1.
// An exception before the commit will cause the transaction to roll back.
scope.Commit();
}
}
Важно то, что TransactionManager позволит вам создавать вложенные области действия - строка «Выполнить вещи с базой данных» может вызватькуча других методов, каждый из которых создает свои собственные области, которые совместно используют транзакцию.Все области должны быть зафиксированы, или все будет откатано.
Все это очень похоже на то, как работает материал в пространстве имен System.Transactions , и я бы порекомендовал вам посмотретьна это тоже.
А затем ваша служебная программа, упрощающая код, если вы все еще хотите их, выглядит следующим образом:
public static void Execute(Action<ITransactionScope> action)
{
using( var scope = TransactionManager.BeginTransaction() )
{
action(scope);
scope.Commit();
}
}
public static TResult Execute<TResult>(Func<ITransactionScope, TResult> func)
{
using( var scope = TransactionManager.BeginTransaction() )
{
var result = func(scope);
scope.Commit();
return result;
}
}