Я склонен согласиться с «неявным» откатом на основе путей исключения.Но, очевидно, это зависит от того, где вы находитесь в стеке и что вы пытаетесь выполнить (то есть класс DBTranscation перехватывает исключение и выполняет очистку, или он пассивно не "фиксирует"?).
Вот случай, когда неявная обработка имеет смысл (возможно):
static T WithTranaction<T>(this SqlConnection con, Func<T> do) {
using (var txn = con.BeginTransaction()) {
return do();
}
}
Но, если API другой, обработка commit тоже может быть (предоставлена, это:
static T WithTranaction<T>(this SqlConnection con, Func<T> do,
Action<SqlTransaction> success = null, Action<SqlTransaction> failure = null)
{
using (var txn = con.BeginTransaction()) {
try {
T t = do();
success(txn); // does it matter if the callback commits?
return t;
} catch (Exception e) {
failure(txn); // does it matter if the callback rolls-back or commits?
// throw new Exception("Doh!", e); // kills the transaction for certain
// return default(T); // if not throwing, we need to do something (bogus)
}
}
}
Я не могу вспомнить слишком много случаев, когда явный откат является правильным подходом, за исключением случаев, когда необходимо применить строгую политику контроля за изменениями. Но опять же, я немного медленнеепоглощение.