Search code examples
c#asp.netsql-servertransactionstransactionscope

Transaction Scope and Multiple Regions


Does transaction scope operate across multiple regions? If I have 2 Processes, one that opens a connection and transaction, performs a insert command then calls another process before the transaction is closed, Will the original transaction take into account if transaction 2 fails? Here is the example code below.

Region 1:

public static void process1()
{
    using (SqlConnection conn = new SqlConnection(Connections.conn()))
    {
        //Open the connection
        conn.Open();

        try
        {
            //Create A new Sql transaction.
            using (var trans = new System.Transactions.TransactionScope())
            {
               using (SqlCommand insert = new SqlCommand
               {
                CommandType = CommandType.Text,
                CommandText = sql,
                Connection = conn,
                CommandTimeout = 300
                })
                {                            
                    insert.ExecuteNonQuery();
                }
            process2()
            trans.complete();
            }
         }
        catch (System.Data.SqlClient.SqlException ex)
        {
            string msg = "Insert Error:";
            msg += ex.Message;
            throw new Exception(msg);
        }
    }
}

Region 2

public static void process2()
{
    using (SqlConnection conn = new SqlConnection(Connections.conn()))
    {
        //Open the connection
        conn.Open();

        try
        {
            //Create A new Sql transaction.
            using (var trans2 = new System.Transactions.TransactionScope())
            {
               using (SqlCommand insert = new SqlCommand
               {
                CommandType = CommandType.Text,
                CommandText = sql,
                Connection = conn,
                CommandTimeout = 300
                })
                {                            
                    insert.ExecuteNonQuery();
                }
            trans2.complete();
            }
         }
        catch (System.Data.SqlClient.SqlException ex)
        {
            string msg = "Insert Error:";
            msg += ex.Message;
            throw new Exception(msg);
        }
    }
}

In my application process 2 is dependant on process 1's success. If process 1 is successful and process 2 is not then the result of process 1 is useless.

I understand that when the commans execute in the same transaction block they will both fail if one does but as I coded my application to do it accorss different regions I was wondering if the same applied in this situation. I would rather not having to recode two different processes together.

Thanks in advance,

Dan


Solution

  • If this is just two blocks of code within a single C# file, then to make sure either both processes happen or neither happen, you would want to wrap your call to those functions in a transaction scope as well. Like so:

    using (var tx = new TransactionScope()) {
         process1();
         process2();
         tx.Complete();
    }
    

    This way if either process1 or process2 fails, both will be rolled back.