Why use a statement for DbTransaction in ADO.NET/C#?

I figured out implicit rollback (which usually happens when an exception occurs and Dispose is called) is not guaranteed across all providers. However, many examples use:

using (DbTransactio txn = cnctn.BeginTransaction())

      

Is there a reason for this?

+3


source to share


2 answers


The simplest answer is "because it implements IDisposable

". Any type that implements IDisposable

: it's your job to dispose of it appropriately. In this case, with procedural code, the easiest way to do this is with an instruction using

.

In this particular case, the answer would be: because in case of an error, you want the transaction to rollback rather than leaving it in the GC. Personally, I would most likely use catch

to Rollback

, but hopefully it Dispose()

already does. However, I would not rely on this myself if it was not documented. For example:

using(var tran = conn.BeginTransaction()) {
    try {
        // do stuff...
        tran.Commit();
    } catch {
        tran.Rollback();
        throw;
    }
}

      



Note that, where applicable, TransactionScope

" Dispose()

unmarked complete" is the expected way to signal a rollback:

using(var tran = new TransactionScope()) {
    // do stuff...
    tran.Complete();
}

      

+5


source


If you have code like this:

DbTransactio txn = cnctn.BeginTransaction();

// do something which throws an exception

txn.Commit();

      

the transaction will not rollback until the garbage collector decides to collect the transaction object (note that this will only work if the implementing class IDisposable

should remove the template ).

You could of course do this:

DbTransaction txn = cnctn.BeginTransaction();
try
{
    // do something which throws an exception

    txn.Commit();
}
finally  
{
    txn.Dispose();
}

      



but it's not as readable as

using (var txn = cnctn.BeginTransaction())
{
    // do something which throws an exception

    txn.Commit();
}

      

Edit:

I figured out implicit rollback (which usually happens when an exception occurs and Dispose is called) is not guaranteed across all providers.

I haven't seen a single provider that doesn't support it. Since IDbTransaction do inherit IDisposable

, all implementations must use Dispose()

to rollback the transaction.

+5


source







All Articles