4

I am working with Visual Studio 2012 and MS SQL Server 2008 R2.

In my code I am using DbConnection and DbTransaction. This is my code:

DbConnection dbConnection = null;
DbTransaction dbTransaction = null;

try
{
   dbConnection = DbProviderFactories.GetFactory("System.Data.SqlClient").CreateConnection();
   dbConnection.ConnectionString = connectionString;
   dbConnection.Open();
   dbTransaction = dbConnection.BeginTransaction();
   // do my work using dbConnection and dbTransaction
   dbTransaction.Commit();
} 
catch (MyWorkFailedException mwfe)
{
   dbTransaction.Rollback();
   throw;
}
finally
{
   if (dbConnection != null)
   {
      dbConnection.Close();
      dbConnection.Dispose();
   }
}

Is it possible that dbTransaction.Commit(); or dbTransaction.Rollback(); throws an exception?

If yes then how to handle it in my code? How c# programmers usually handles this situation? Or they dont handle this situation?

5
  • 3
    Why there's not a single using in your code? Commented Oct 29, 2015 at 22:30
  • @SergRogovtsev is not the way I am using try finally same as using using for DbConnection? If yes then it is just a preference and old habbit. Commented Oct 30, 2015 at 12:33
  • 1
    It's mostly the same, but you can make mistakes easily (for example, in your code you could try to rollback a nonexistent transaction). using is good pattern you should leverage. Commented Oct 30, 2015 at 14:38
  • @sergRogovtsev "using is good pattern you should leverage" -> not always in case of WCF client (known bug) should you wrap it within try catch finnaly to handle the dispose explicitly Commented Mar 17, 2019 at 22:28
  • @bet, this is not a WCF client. Commented Mar 18, 2019 at 9:08

3 Answers 3

6

Yes, both Commit and Rollback can throw exceptions. However, these should probably be propagated up and either logged or displayed as an error to the user. How you want to handle the error is entirely up to you, but typically the errors will be due to a closed connection. Secondly, you should leverage using

using (var dbConnection  = DbProviderFactories.GetFactory("System.Data.SqlClient").CreateConnection())
{
    dbConnection.ConnectionString = connectionString;
    dbConnection.Open();
    using (var dbTransaction = dbConnection.BeginTransaction())
    {
        //Do work here

        dbTransaction.Commit();
    }
}

DbTransaction will automatically rollback on its dispose method (assuming it hasn't been committed). Exceptions thrown by this code typically are not something you can gracefully handle. For the most part, they would come from SQL errors (invalid syntax, FK errors, etc), or a closed connection.

As long as you've got a good logging system in place, the above code should be all you need.

Sign up to request clarification or add additional context in comments.

2 Comments

Why do you need this rather than the clear new SqlConnection()?
I do need to propagate up exceptions and display as an error to the user. I made the change in my code above to throw MyWorkFailedException again after rollback. Assume I have a custom exception InfrastructureException; how would you throw this exception in your code if commit or rollback failed?
2

Use TransactionScope instead which has only Complete(). Once it has been disposed it will rollback the underlying transaction. Any exception will cause the underlying transaction to be rolledback as well:

using (var scope = new TransactionScope())
using (var connection = new SqlConnection(...))
{
    // do stuff

    scope.Complete();
}

2 Comments

I thought TransactionScope is only needed if your transaction span multiple databases?
Actually not, it works with any compliant provider, and its somewhat cleaner than using DbTransactions
1

You handle the exception in any of the methods (both Commit and Rollback) as failure in transaction. If you want/have to, you can clean up something in your C# code. Database cleanup will be handled automatically (at least, for ACID-compliant DB).

1 Comment

The one in Rob's answer will do.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.