Question

I want to use Rollback() or commit() functions after multiple process.

There is no error, but it does not commit() to update DB.

Here is my example code,

public void startTransaction(){
    using(Ads_A_Connection = new AdsConnection(Ads_A_connection_string))
    using(Ads_B_Connection = new AdsConnection(Ads_B_connection_string))
    {
        Ads_A_Connection.Open();
        Ads_B_Connection.Open();

        AdsTransaction aTxn = Ads_A_Connection.BeginTransaction();
        AdsTransaction bTxn = Ads_B_Connection.BeginTransaction();

        try{
            string aResult = this.process1(Ads_A_Connection);       
            this.process2(Ads_B_Connection, aResult);       
            this.process3(Ads_A_Connection. Ads_B_Connection);

            aTxn.Commit();
            bTxn.Commit();
            // there is no error, but it couldn't commit.
        }catch(Exception e){
            aTxn.Rollback();
            bTxn.Rollback();
        }
    }
}

public string process1(conn){
    // Insert data
    return result;
}

public void process2(conn. aResult){
    // update
}

public void process3(aConn, bConn){
    // delete
    // update
}

I guess, its because out of using scope. because I tried to put all the code into startTransaction() method, then it works. but it look too dirty.

How can I use rollback() or commit() after multiple (METHOD) process?

anybody know, please advice me.

Thanks!

[EDIT]

I just add TransactionScope before connection,

using (TransactionScope scope = new TransactionScope())
{
   using(Ads_A_Connection = new AdsConnection(Ads_A_connection_string))
   using(Ads_B_Connection = new AdsConnection(Ads_B_connection_string))
   {
     .
     .

but it makes an error, it say "Error 5047: The transaction command was not in valid sequence."

I need a little more hint please :)

Was it helpful?

Solution

To extend what Etch mentioned, their are several issues with manually managing transactions on your connections:

  • You need to pass the SQL connection around your methods
  • Need to manually remember to commit or rollback when you are finished
  • If you have more than one connection to manage under a transaction, you should really use DTC or XA to enroll the transactions into a Distributed / 2 phase transaction.

TransactionScopes are supported with the Advantage Database Server, although you will need to enable the MSDTC service and possibly also enable XA compliance.

Note that I'm assuming that the advantage .NET client has some sort of connection pooling mechanism - this makes the cost of obtaining connections very lightweight.

Ultimately, this means that your code can be refactored to something like the following, which is easier to maintain:

private void Method1()
{
    using(Ads_A_Connection = new AdsConnection(Ads_A_connection_string))
    {
        Ads_A_Connection.Open();
        string aResult = this.process1(Ads_A_Connection);       
    } // Can logically 'close' the connection here, although it is actually now held by the transaction manager
}

private void Method2()
{
    using(Ads_B_Connection = new AdsConnection(Ads_B_connection_string))
    {
        Ads_B_Connection.Open();
        this.process2(Ads_B_Connection, aResult);       
    } // Can logically 'close' the connection here, although it is actually now held by the transaction manager
}


public void MyServiceWhichNeedToBeTransactional(){
    using(TransactionScope ts = new TransactionScope()) { // NB : Watch isolation here. Recommend change to READ_COMMITTED
        try{
           Method1();
           Method2();
           ts.Complete();
        }
        catch(Exception e){
          // Do Logging etc. No need to rollback, as this is done by default if Complete() not called
        }
    }
}

OTHER TIPS

TransactionScope is your friend!

TransactionScope

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top