Есть 2 основных вида транзакций; транзакции соединения и окружающие транзакции. Транзакция соединения (например, SqlTransaction) напрямую связана с соединением db (например, SqlConnection), что означает, что вам нужно постоянно передавать соединение - ОК в некоторых случаях, но не разрешать «создавать / использовать / освобождать» использование, и не позволяет кросс-дБ работать. Пример (отформатированный для пробела):
using (IDbTransaction tran = conn.BeginTransaction()) {
try {
// your code
tran.Commit();
} catch {
tran.Rollback();
throw;
}
}
Не слишком грязно, но ограничено нашей связью "Конн". Если мы хотим вызвать разные методы, нам нужно передать «conn».
Альтернатива - внешняя транзакция; Впервые в .NET 2.0 объект TransactionScope (System.Transactions.dll) позволяет использовать различные операции (подходящие поставщики автоматически подключаются к внешней транзакции). Это позволяет легко встраиваться в существующий (не транзакционный) код и общаться с несколькими провайдерами (хотя DTC будет участвовать, если вы говорите с более чем одним).
Например:
using(TransactionScope tran = new TransactionScope()) {
CallAMethodThatDoesSomeWork();
CallAMethodThatDoesSomeMoreWork();
tran.Complete();
}
Обратите внимание, что эти два метода могут обрабатывать свои собственные соединения (открывать / использовать / закрывать / удалять), но они будут тихо становиться частью транзакции окружения без необходимости что-либо передавать.
Если ваш код ошибки, Dispose () будет вызван без Complete (), поэтому он будет откат. Поддерживается ожидаемое вложение и т. Д., Хотя вы не можете откатить внутреннюю транзакцию, но завершить внешнюю транзакцию: если кто-то недоволен, транзакция отменяется.
Другое преимущество TransactionScope заключается в том, что он не привязан только к базам данных; любой провайдер, поддерживающий транзакции, может использовать его. WCF, например. Или есть даже некоторые TransactionScope-совместимые объектные модели (например, классы .NET с возможностью отката - возможно, проще, чем сувенир, хотя я никогда не использовал этот подход сам).
В общем, очень, очень полезный объект.
Некоторые предостережения:
- В SQL Server 2000 TransactionScope немедленно перейдет в DTC; это исправлено в SQL Server 2005 и выше, он может использовать LTM (намного меньше накладных расходов), пока вы не поговорите с 2 источниками и т. д., когда он повышен до DTC.
- Существует сбой, который означает, что вам может понадобиться настроить строку подключения