views:

1033

answers:

3

I've got an IDbTransaction in a using statement but I'm unsure if it will be rolled back if an exception is thrown in a using statement. I know that a using statement will enforce the calling of Dispose()...but does anyone know if the same is true for Rollback()?

Update: Also, do I need to call Commit() explicitly as I have below or will that also be taken care of by the using statement?

My code looks sort of like this:

using Microsoft.Practices.EnterpriseLibrary.Data;

...

using(IDbConnection connection = DatabaseInstance.CreateConnection())
{
    connection.Open();

    using(IDbTransaction transaction = connection.BeginTransaction())
    {
       //Attempt to do stuff in the database
       //potentially throw an exception
       transaction.Commit();
    }
}
+8  A: 

Apparently yes. This is how SqlInternalTransaction's Dispose method (which SqlTransaction's Dispose calls) looks like from Reflector:

private void Dispose(bool disposing)
{
    Bid.PoolerTrace("<sc.SqlInteralTransaction.Dispose|RES|CPOOL> %d#, Disposing\n", this.ObjectID);
    if (disposing && (this._innerConnection != null))
    {
        this._disposing = true;
        this.Rollback(); // there you go
    }
}
ssg
It will, I even tested this once by explicitly throwing an exception.
Pawel Krakowiak
That's awesome! One question on my mind now though is do I need to explicitly call commit...or will the using statement handle that one too effectively making my current commit statement redundant.
mezoid
That *is* awesome, but does it work for other implementations of IDbTransaction if you're using it for cross-db compatibility?
Matt Hamilton
@mezoid: Commit will never happen automatically.@matt: They should, by design.
ssg
A: 

I believe that if there's an exception such that Commit() was never called, then the transaction will automatically rollback.

Tommy Hui
+1  A: 

You have to call commit. The using statement will not commit anything for you.

jhale