Illep
Illep

Reputation: 16851

How to know if transaction scope was successful or not

I need to know if my transaction scope was successful or not. As in if the records were able to be saved in the Database or not.

Note: I am having this scope in the Service layer, and I do not wish to include a Try-Catch block.

bool txExecuted;

using (var tx = new TransactionScope())
{
   //code
   // 1 SAVING RECORDS IN DB
   // 2 SAVING RECORDS IN DB

   tx.Complete();
   txExecuted = true;
}

if (txExecuted ) {

   // SAVED SUCCESSFULLY
} else {
  // NOT SAVED. FAILED
}

Upvotes: 0

Views: 1578

Answers (2)

William Xifaras
William Xifaras

Reputation: 5312

To be clear, calling the Complete() method is only an indication that all operations within the scope are completed successfully.

However, you should also note that calling this method does not guarantee a commit of the transaction. It is merely a way of informing the transaction manager of your status. After calling this method, you can no longer access the ambient transaction via the Current property, and trying to do so results in an exception being thrown.

The actual work of commit between the resources manager happens at the End Using statement if the TransactionScope object created the transaction.

Since you are using ADO.NET, ExecuteNonQuery will return the number of rows affected. You can do a database lookup after the commit and outside of the using block.

In my opinion, its a mistake not to have a try/catch. You want to catch the TransactionAbortedException log the exception.

try
{
    using (var scope = new TransactionScope())
    {
        using (var conn = new SqlConnection("connection string"))
        {

        }

        // The Complete method commits the transaction. If an exception has been thrown,
        // Complete is not  called and the transaction is rolled back.
        scope.Complete();
    }
}
catch (TransactionAbortedException ex)
{
    // log
}

Upvotes: 0

Caius Jard
Caius Jard

Reputation: 74660

The commented code will be doing updates, and will probably be implemented using ExecuteNonQuery() - this returns an int of the number of rows affected. Keep track of all the return values to know how many rows were affected.

The transaction as a whole will either succeed or experience an exception when it completes. If no exception is encountered, the transaction was successful. If an exception occurs, some part of the transaction failed; none of it took place

By considering these two facts (records affected count, transaction exception or no) you can know if the save worked and how many rows were affected

I didn't quite understand the purpose of txExecuted- if an exception occurs it will never be set and the if will never be considered. The only code that will thus run is the stuff inside if(true). I don't see how you can decide to not use a try/catch and hope to do anything useful with a system that is geared to throw an exception if something goes wrong; you saying you don't want to catch exceptions isn't going to stop them happening and affecting the control flow of your program

Upvotes: 1

Related Questions