Click here to Skip to main content
15,881,711 members
Articles / Programming Languages / C#
Article

Transaction Aware Table-adapters in .NET 2.0

Rate me:
Please Sign up or sign in to vote.
4.89/5 (16 votes)
5 Dec 2007CPOL3 min read 85.7K   393   30   31
A quick and elegant way to add transaction capabilities to your table-adapters

Introduction

Much has been said about missing support for atomic transactions in .NET 2.0 when using table adapters that get generated by the dataset designer. This article provides a ready-to-use base-class that by injecting it into a table-adapter's inheritance line equips it with transaction capabilities.

Discussion of Approaches

One way to get around the aforementioned limitations is to configure your server to have DTC (Distributed Transaction Coordination) enabled. In that case, you can use TransactionScope instances guarding actions like modifications through table adapters. However, if you don't want to or cannot change the server's configuration, TransactionScope is not an option.

Others on The Code Project and other sites have explained how to enable transactions for table adapters. The basic idea always is to attach an SqlTransaction to all commands of a table-adapter. If multiple table-adapters are used, share the same transaction across all commands of all adapters. What makes this a little difficult is that a generated table-adapter keeps its SqlDataAdapter property Adapter private, but transaction code requires modifying the property.

There are several approaches to solve this issue. For instance Avoiding DTC with Typed DataSets and SQL Server 2000 suggests adding transaction code in the form of partial classes. As the partial extension lives in the same scope as the original table-adapter, it can also access its private properties. The major disadvantage here is that partial classes have to be created for each generated table adapter.

A much more elegant approach is mentioned in this post (unfortunately in German): use reflection to get your hands at those properties. The article also mentions a small detail I found very interesting: when editing a table-adapter in designer-mode, you are actually able to change its base class! So instead of the default base-class Component you can fill in your own base-class. If you now provide such a base-class that is derived from Component and implements the transaction stuff through reflection, usage becomes simple and elegant. And this is exactly what I did: putting together such a handy base-class called TransactionSupport.

Using the Code

To take advantage of the base class is very simple: First download the class source code and drop it into your project. Then, for all tables in your dataset that require transaction support, change the table adapter's base-class like this:

  1. Select the table-adapter (not the table) in the dataset designer, such that it becomes visible in the properties view.

    Screenshot - ta-properties.png

  2. Change the property BaseClass from System.ComponentModel.Component to the class BizWiz.TransactionSupport I provided like is shown in the screenshot.

And that's it. Do this for each table adapter required. Then you can write code of the following pattern:

C#
// begin transaction and share it among all participating table-adapters:
customerTableAdapter.BeginTransaction();
orderTableAdapter.Transaction = customerTableAdapter.Transaction;

// now start the modifications:
try
{
    // do modifications here, throw exceptions if things go wrong...
    // ...

    // ok, all is well, commit transaction:
    customerTableAdapter.CommitTransaction();
}
catch( Exception e )
{
    // if anything went wrong, roll-back transaction
    customerTableAdapter.RollbackTransaction();
}

You can choose any of the participating table-adapters to perform commit or rollback, but I make it good practice to have one dedicated transaction master, that is doing it all: BeginTransaction(), CommitTransaction()and RollbackTransaction().

History

Date Comment
2007-SEP-15Uploaded modified version of base that looks for Connection property of generated table adapters in public as well as non-public scope, as this seems to differ throughout installations.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) BMW AG
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralNice article Pin
AJMAL SHAHZAD13-Jul-12 20:13
AJMAL SHAHZAD13-Jul-12 20:13 
GeneralNice article Pin
AJMAL SHAHZAD13-Jul-12 20:12
AJMAL SHAHZAD13-Jul-12 20:12 
GeneralTransaction property returning null Pin
SCourt.NET24-Aug-10 10:19
SCourt.NET24-Aug-10 10:19 
GeneralRe: Transaction property returning null Pin
SCourt.NET24-Aug-10 10:28
SCourt.NET24-Aug-10 10:28 
GeneralThank you very much!!! Pin
Houman Masnavi ,Phd10-Jun-10 3:49
Houman Masnavi ,Phd10-Jun-10 3:49 
GeneralFabulous work.... Pin
madhuraj00119-May-10 2:45
madhuraj00119-May-10 2:45 
GeneralHi all, Pin
bruce2willis23-Jun-09 7:52
bruce2willis23-Jun-09 7:52 
GeneralThank You Pin
George_Botros19-Mar-09 5:52
George_Botros19-Mar-09 5:52 
GeneralIf anyone is looking for a VB version of this... Pin
egbdfine29-Jan-09 7:03
egbdfine29-Jan-09 7:03 
GeneralRe: If anyone is looking for a VB version of this... Pin
cbankovic18-Aug-10 5:21
cbankovic18-Aug-10 5:21 
Generalweird ... Pin
tomtom198011-Nov-08 2:30
tomtom198011-Nov-08 2:30 
GeneralRe: weird ... Pin
Mike Pagel11-Nov-08 2:53
Mike Pagel11-Nov-08 2:53 
QuestionHelp please on MySql + C# Pin
Seuss18-Sep-08 1:58
Seuss18-Sep-08 1:58 
AnswerRe: Help please on MySql + C# Pin
Tim@Kin15-Dec-08 21:57
Tim@Kin15-Dec-08 21:57 
QuestionHelp please on MySQL and C# Pin
Seuss18-Sep-08 0:01
Seuss18-Sep-08 0:01 
AnswerRe: Help please on MySQL and C# Pin
Mike Pagel18-Sep-08 0:34
Mike Pagel18-Sep-08 0:34 
QuestionRe: Help please on MySQL and C# Pin
Seuss18-Sep-08 1:07
Seuss18-Sep-08 1:07 
GeneralWorks beautifully Pin
NeedTechHelp13-Aug-08 11:44
NeedTechHelp13-Aug-08 11:44 
Generalpublic vs. private scope on connection Pin
Josh Ryon15-Jul-08 10:31
Josh Ryon15-Jul-08 10:31 
GeneralTransaction with strongly typed dataset and multiple table adapters Pin
Anil Pandya6-Jan-08 23:43
Anil Pandya6-Jan-08 23:43 
if you want to implement transaction with strongly typed dataset it is some what trikey,

Table adapters which are created in typed datasets are implemented in partial classes by visual studio 2005,

if you want to use multiple table adapters in one transaction than you have to follow this sceanario.....

implement partial classes foR all your table adapters like this use onky one connection object for all, (assign new connection to first adapter and to other pass just reference of that connection)

Partial classes are used to extend the functionality provided by TableAdapters. They are to be written in “App_Code” folder. In partial classes, the physical files are scattered any where in the project with the same name like “public partial class <classname>” but when project is compiled all the physical files are combined like one physical file and make the whole class

Example of a partial class

using System;
using System.Data;
using System.Data.SqlClient;
namespace dsGroundSelectTableAdapters
{
public partial class ADAPTERNAME_TableAdapter
{
private SqlTransaction _transaction;
private SqlTransaction Transaction {
get
{ return this._transaction; }
set {
this._transaction = value; }
}
public SqlConnection GetConnection()
{
return this.Connection;
}
public void SetConnection(ref SqlConnection Conn)
{
this.Connection = Conn;
}
public SqlTransaction GetTransaction()
{
return this.Transaction;
}
public void SetTransaction(ref SqlTransaction Trans)
{
this.Transaction = Trans;
foreach (SqlCommand command in this.CommandCollection)
{
command.Transaction = this.Transaction;
}
this.Adapter.InsertCommand.Transaction = this.Transaction;
}
public void BeginTransaction()
{
// Open the connection, if needed
if (this.Connection.State != ConnectionState.Open)
{
this.Connection.Open();
}
// Create the transaction and assign it to the Transaction property
this.Transaction = this.Connection.BeginTransaction();
// Attach the transaction to the Adapters
foreach (SqlCommand command in this.CommandCollection)
{
command.Transaction = this.Transaction;
}
this.Adapter.InsertCommand.Transaction = this.Transaction;
}
public void CommitTransaction()
{
// Commit the transaction
this.Transaction.Commit();
// Close the connection
this.Connection.Close();
}
public void RollbackTransaction()
{
// Rollback the transaction
this.Transaction.Rollback();
// Close the connection
this.Connection.Close();
}
}}


************************
and in code behind file

//////create object of all your adapters

(1) dsDATASETNAMETableAdapters.ADAPTERNAMETableAdapter daOBJECT1 = new dsDATASETNAMETableAdapters.ADAPTERNAMETableAdapter();

(2) dsDATASETNAMETableAdapters.ADAPTERNAMETableAdapter daOBJECT2 = new dsDATASETNAMETableAdapters.ADAPTERNAMETableAdapter();

(3) dsDATASETNAMETableAdapters.ADAPTERNAMETableAdapter daOBJECTn = new dsDATASETNAMETableAdapters.ADAPTERNAMETableAdapter();

/////////create connection
///////// assign it to first adapter object and give others a refernce ////////to the same

/////////all operation must be performed using first adapter object

//even they all are refernced by a same connectin they all are in one ///////transaction...

SqlConnection Conn= new SqlConnection();
Conn=daOBJECT1.GetConnection();
daOBJECT2.SetConnection(ref Conn);
daOBJECTn.SetConnection(ref Conn);

daOBJECT1.BeginTransaction();

SqlTransaction trnTrans = daOBJECT1.GetTransaction();
daOBJECT2.SetTransaction(ref trnTmpTrans);
daOBJECTn.SetTransaction(ref trnTmpTrans);
try
{
//EXECUTE YOUR QUERIES HERE
// YOU CAN CALL FUNCTIONS TO UPDATE INSERT DATA
//insertDATAInTable();
//updateDATATable();

daOBJECT1.CommitTransaction();
}
catch (Exception ex)
{
daOBJECT1.RollbackTransaction();
}

***********************************
Anil Pandya
Senior Software Programmer
Mumbai
+919920066603

anil

GeneralRe: Transaction with strongly typed dataset and multiple table adapters Pin
Mike Pagel7-Jan-08 0:19
Mike Pagel7-Jan-08 0:19 
GeneralRe: Transaction with strongly typed dataset and multiple table adapters Pin
Anil Pandya7-Jan-08 17:48
Anil Pandya7-Jan-08 17:48 
GeneralConnection is Public Pin
tmv1912-Sep-07 13:21
tmv1912-Sep-07 13:21 
AnswerRe: Connection is Public [modified] Pin
Mike Pagel12-Sep-07 20:26
Mike Pagel12-Sep-07 20:26 
GeneralRe: Connection is Public Pin
tmv1913-Sep-07 5:12
tmv1913-Sep-07 5:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.