Click here to Skip to main content
6,293,171 members and growing! (11,361 online)
Email Password   helpLost your password?
Database » Database » General     Intermediate

Easier Database Transactions - Extending the Using Statement to Perform Automatic Database Transactions

By Chad Z. Hower aka Kudzu

Any user who works with database updates uses transactions. Transactions in ADO.NET are done using a transaction object, and a try..catch, but there is an easier, one might even say a more C# way to handle database transactions.
C#, SQL, Windows, .NET CF, .NET 1.0, .NET 1.1, .NET 2.0, ADO.NET, SQL 2000, SQL 2005, VS.NET2003, VS2005, SQL CE, DBA, Dev
Posted:25 Oct 2004
Views:69,538
Bookmarked:44 times
Announcements
Loading...
 
Search    
Advanced Search
printPrint   Broken Article?Report       add Share
  Discuss Discuss   Recommend Article Email
18 votes for this article.
Popularity: 4.83 Rating: 3.85 out of 5
1 vote, 5.6%
1

2
3 votes, 16.7%
3

4
14 votes, 77.8%
5

Overview

Any user who works with database updates uses transactions. Transactions in ADO.NET are done using a transaction object, and a try..catch, but there is an easier, one might even say a more C# way to handle database transactions.

Visual Basic .NET Users

Because this technique relies on the using statement which is C# specific, this technique cannot be applied in Visual Basic .NET. However, rumors are that Visual Studio .NET 2005 will include a similar statement for Visual Basic.

Transactions the Normal Way

Here is an example of a database transaction the normal way. This is a condensed version of the example on MSDN.

using (OleDbTransaction xTx = _DB.BeginTransaction()) {
    try {
        OleDbCommand xCmd = _DB.CreateCommand();
        xCmd.Transaction = xTx;
        xCmd.CommandText = "Insert into Person (Name, Telephone)" + 
                           " values ('Normal One', '(412) 555-1212')";
        xCmd.ExecuteNonQuery();
        if (chckThrow.Checked) {
            throw new Exception("Test Exception");
        }
        xCmd.CommandText = "Insert into Person (Name, Telephone)" + 
                           " values ('Normal Two', '(423) 555-1212')";
        xCmd.ExecuteNonQuery();
        xTx.Commit();
    }
    catch (Exception xException) {
        xTx.Rollback();
        throw xException;
    }
}

Transactions the Easy Way

With my method, the code does the same, but becomes a bit shorter, cleaner, and even a bit more C# like.

using (Transaction xTx = new Transaction(_DB)) {
    OleDbCommand xCmd = _DB.CreateCommand();
    ((IDbCommand)xCmd).Transaction = xTx.DBTransaction;
    xCmd.CommandText = "Insert into Person (Name, Telephone)" + 
                       " values ('Object One', '(412) 555-1212')";
    xCmd.ExecuteNonQuery();
    if (chckThrow.Checked) {
        throw new Exception("Test Exception");
    }
    xCmd.CommandText = "Insert into Person (Name, Telephone)" + 
                       " values ('Object Two', '(423) 555-1212')";    
    xCmd.ExecuteNonQuery();
    xTx.Commit();
}

Demo Project

The demo project demonstrates this and allows simulated exceptions. The demo project uses the included Access database file for simplicity. However, the included class works with any ADO.NET data source.

How it Works

The using statement in C# causes the dispose to be called when the block is exited. By implementing a Dispose, and checking to see if the transaction has been committed, the transaction class can then determine whether or not to call rollback. There is no need to rethrow any exception that may be in progress, because C# automatically continues the exception path as part of the handling of the using block.

Transaction Class Source

public class Transaction : IDisposable {

    private IDbConnection _DB;
    private IDbTransaction _DBTransaction;

    public IDbTransaction DBTransaction {
      get { return _DBTransaction; }
    }

    public Transaction(IDbConnection aDB) : this(aDB, true) {
    }

    public Transaction(IDbConnection aDB, bool aHandle) {
      if (aHandle) {
        _DB = aDB;
        _DBTransaction = _DB.BeginTransaction();
      }
    }

    public void Commit() {
      if (_DB != null) {
        _DBTransaction.Commit();
        _DBTransaction.Dispose();
        _DB = null;
      }
    }

    public void Dispose() {
      if (_DB != null) {
        _DBTransaction.Rollback();
        _DBTransaction.Dispose();
        _DB = null;
      }
    }
}

Conclusion

This class purely adds syntactic sugar to your code and makes performing transactions a little bit easier. The functionality is the same. But when working with transactions and having to manually create this structure each time, the shorter version is a lot easier to type, as well as read later when working in the code again.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Chad Z. Hower aka Kudzu


Member
Chad Z. Hower, a.k.a. Kudzu
"Programming is an art form that fights back"
Website: http://www.KudzuWorld.com
Blogspace: http://www.KudzuWorld.com/blogs/
Speaking Profile: http://www.woo-hoo.net/

Formerly the Regional Developer Adviser (DPE) for Microsoft MEA (Middle East and Africa), he was responsible for 85 countries spanning 4 continents and crossing 10 time zones. Now Chad is Microsoft MVP and a Microsoft Regional Director covering Europe, Middle East, Africa, and Asia and a professional speaker at popular developer conferences worldwide. Chad was once introduced as having "mastered more languages than a United Nations translator." Chad is the author of the book Indy in Depth and has contributed to several other books on network communications and general programming. Chad writes regularly for the Software Developer Network Magazine (Dutch), and occasionally for other magazines. Chad is an expatriate who travels extensively year round. Chad has lived in Canada, Cyprus, Jordan, Russia, Turkey, and the United States. In total Chad has visited more than 50 countries, visiting most of them many times.
Occupation: Software Developer (Senior)
Location: Cyprus Cyprus

Other popular Database articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 11 of 11 (Total in Forum: 11) (Refresh)FirstPrevNext
GeneralDifferent implementation of the transaction [modified] PinmemberPIEBALDconsult12:26 17 Mar '08  
GeneralRe: Different implementation of the transaction PinmemberChad Z. Hower aka Kudzu14:31 17 Mar '08  
GeneralClose? PinsussAnonymous13:39 31 Oct '04  
GeneralRe: Close? PinmemberChad Z. Hower aka Kudzu15:12 31 Oct '04  
GeneralRe: Close? PinmemberAlvaro Mendez10:50 27 May '05  
GeneralNo need to wrap to shorten the code PinsussCandan Akyol10:46 26 Oct '04  
GeneralRe: No need to wrap to shorten the code PinmemberChad Z. Hower aka Kudzu3:18 27 Oct '04  
GeneralThe pattern is almost right... PinmembercasperOne4:06 26 Oct '04  
GeneralRe: The pattern is almost right... PinmemberChad Z. Hower aka Kudzu3:42 27 Oct '04  
GeneralIs shorter always better? PinmemberMark Focas13:13 25 Oct '04  
GeneralRe: Is shorter always better? PinmemberChad Z. Hower aka Kudzu13:25 25 Oct '04  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 25 Oct 2004
Editor: Smitha Vijayan
Copyright 2004 by Chad Z. Hower aka Kudzu
Everything else Copyright © CodeProject, 1999-2009
Web12 | Advertise on the Code Project