Есть 2 основных вида транзакций; транзакции соединения и окружающие транзакции. Транзакция соединения (такая как SqlTransaction) напрямую связана с соединением db (например, SqlConnection), что означает, что вам нужно постоянно передавать соединение - ОК в некоторых случаях, но не позволяет «создавать / использовать / освобождать» использование, и не позволяет кросс-дБ работать. Пример (отформатированный для пробела):
using (IDbTransaction tran = conn.BeginTransaction()) {
try {
// your code
tran.Commit();
} catch {
tran.Rollback();
throw;
}
}
Не слишком грязно, но ограничено нашей связью "conn". Если мы хотим вызвать разные методы, нам нужно передать «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.
- Существует глюк , который означает, что вам может понадобиться настроить строку подключения