24 March 2014

Transaction Example

WCF transaction was explained with below employee service
  1. Create the Employee WCF service to allow client user to insert employee detail
  2. Enable the transaction from server side by setting proper attributes
  3. Create the client application by consuming the Employee Service and insert the employee details
  4. Run the client application to successfully insert the employee detail
  5. Modify the service application to throw exception explicitly after successfully insert statement execution and check the transaction behavior.
Step 1: Create the Employee service that allows the addition of new employee details in DB. Decorate the operation contract with TransactionFlow attribute for enabling the transaction. TransactionFlowOption take three set of values.
  • TransactionFlowOption.Allowed
  • TransactionFlowOption. Mandatory
  • TransactionFlowOption. NotAllowed
[Service Contract]
Public interface IService
{
    [Operation Contract]
    [TransactionFlow (TransactionFlowOption.Allowed)]
    Bool Add Employee (int id, string name, int salary);
}

Step 2:Create the service class which implements the service contract and set the operation behavior with TransactionScopeRequired = true . This attribute is used to enable the service transaction when the client transaction is not available.

Public class Service: IService
{
    [Operation Behavior (TransactionScopeRequired = true)]
    Public bool Add Employee(int id, string name, int salary)
    {
        Try
        {
            //Insert the employee tables inside the transaction
            SqlConnection conn = new SqlConnection (@"Data Source=.\eaudit; Initial 
                                    Catalog=Test01; Integrated Security=SSPI;");
            SqlCommand cmd = new SqlCommand ("INSERT INTO [Test01]. [Dbo].       [Employee] 
                                        VALUES ("+id.ToString ()+",'"+name +"',
                                        "+salary.ToString ()+")", conn);
            cmd.CommandType = System.Data.CommandType.Text;
            conn.Open ();
            cmd.ExecuteNonQuery ();
            conn.Close ();
            Return true;
        }
        Catch (Exception ex)
        {
            //return false;
            Throw new Fault Exception (ex. Message);
        }
    }
}

Step 3: Update the service endpoint to enable transactions for wsHttpBinding by setting the
transaction Flow attribute to true. Setting transaction Flow at config level doesn’t mean
that the service wants to use the client’s transaction in every operation.It is required to set
 the transaction at the service contract level as mention in Step 1.

<system.serviceModel>
   <behaviors>
      <serviceBehaviors>
                        <behavior>
                <serviceMetadata httpGetEnabled="true"/>
                <serviceDebug includeExceptionDetailInFaults="true"/>
            </behavior>
     </serviceBehaviors>
  </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
    <services>
      <service name="Service">
      <endpoint address="" binding="wsHttpBinding" 
           contract="IService" bindingConfiguration="myTransactionBinding"/>
      </service>
    </services>
    <bindings>
      <wsHttpBinding>
        <binding name="myTransactionBinding" transactionFlow="true" ></binding>
      </wsHttpBinding>
    </bindings>
</system.serviceModel>

Step 4: Now service creation is completed and let’s starts with the client application. Create a new console application from add Employee service as Service Reference
 
Static void Main (string [] args) 
{           
   bool result=false;
  Using (Transaction Scope ts = new Transaction Scope (TransactionScopeOption.RequiresNew))
{     Try          {                    EmployeeService.ServiceClient service = New EmployeeService.ServiceClient();     Result = service.AddEmployee (1, "omk", 3000); 
      ts.Complete ();
          }               
      Catch (Exception ex)               
      {                    
        ts.Dispose ();                   
        Console.WriteLine (ex. Message);              
       }
    }          
 if ( result == true )               
 Console.WriteLine ("Employee details add successfully");
 Else  
 Console.WriteLine ("Error while adding employee details");
 Console.ReadLine();  
} 

Output:
Output shows the employee detail is added successfully


Step 6:Now everything
works fine, let’s test the transaction by throwing the exception from server
side after successful execution of employee details insert statement
 Try 
  { 
    //Insert the employee tables inside the transaction 
    SqlConnection conn = new SqlConnection (@"Data Source=.\eaudit;Initial catalog=Test01;     Integrated Security=SSPI;"); 

    SqlCommand cmd = new SqlCommand ("INSERT INTO [Test01].[dbo].[Employee]  
      VALUES ("+id.ToString ()+",'"+name +"',"+salary.ToString()+")", conn);   

    cmd.CommandType = System.Data.CommandType.Text; 
    conn.Open ();
    cmd.ExecuteNonQuery();
    conn.Close ();
     //Throw Exception after successful insert statement execution
   Throw new Exception ("Sample exception for testing");   
    Return true;
   }
   Catch (Exception ex)
    {  
     //return false;
     Throw new Fault Exception (ex. Message); 
   }


Step 7:Run the client application and check the output. Result clearly says that even insert statement is executed successfully and error is thrown after insert statement, DB is not updated. Because all the code execution is comes under the transaction so failure in any module of code will revert back all code execution.


No comments:

Post a Comment