6

I am performing data changes on multiple databases, and I want to implement a transaction that will cover all of the changes.

This is what I currently have:

try
{
    db[1].begintransaction();
    db[1].ExecuteNonQuery();

    db[2].begintransaction();
    db[2].ExecuteNonQuery();

    ...

    db[N].begintransaction();
    db[N].ExecuteNonQuery();

    // will execute only if no exception raised during the process
    for (int a = 0; a < N; a++)
    {
        db[a].Commit();// what if there is an error/exception here
    }
}
catch
{
    for (int a = 0; a < N; a++)
    {
        db[a].RollBack();
    }
}

The problem is that the above would fail horribly if an exception happens during a Commit() (see the comment). Is there any better way of accomplishing this?

Jesse
  • 8,605
  • 7
  • 47
  • 57
Umair Ahmed
  • 11,238
  • 5
  • 33
  • 39

4 Answers4

13

Use the TransactionScope class like this:

using (TransactionScope ts = new TransactionScope())
{
    //all db code here

    // if an error occurs jump out of the using block and it will dispose and rollback

    ts.Complete();
}

The TransactionScope class will automatically convert to a distributed transaction if necessary.

Jesse
  • 8,605
  • 7
  • 47
  • 57
keithwarren7
  • 14,094
  • 8
  • 53
  • 74
  • @Jesse, I think for transaction across databases, even in latest version of .Net, Microsoft Distributed Transaction Coordinator will be needed. I couldn't get why you said it will not be needed? – Sunil Jul 12 '14 at 22:56
  • @Sunil You are totally right. It was a misunderstanding on my part of the .NET Framework at the time. I will proceed to remove the erroneous comment. Thanks for notifying me! =) – Jesse Jul 12 '14 at 23:23
1

Using transactionScope is the answer. It even works with different DBMS!!!

Transactions over multiple databases

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
David Espart
  • 11,520
  • 7
  • 36
  • 50
0

As cletus said, you need some kind of two-phase commit. As the article states, this doesn't always work in practice. If you need a robust solution, you must find a way to serialize the transactions in such a way that you can do them one after the other and roll them back individually.

Since this depends on the specific case on which you don't provide any details, I can't give you ideas how to attack this.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
0

If you wish to execute transaction across multiple instances of SQL Server then take a look at the Microsoft Distributed Transaction Coordinator documentation

John Sansom
  • 41,005
  • 9
  • 72
  • 84