WCF Articles

WCF Transactions

WCF Transactions

Transactions consists of set of activities in which all activities succeeds or fails.
Transactions follows ACID properties .

  1. Atomicity ( A ) – means all transactions are either committed or rolled back to previous state

  2. Consistency ( C ) – means changes made by transactions causes transformation from one state to other

  3. Isolation ( I ) – prevents one transaction to see uncommitted changes belonging to other concurrent transaction

  4. Durability ( D ) – means updates are persistent even in case of failure

To add transaction support to a WCF service, you will take the following actions:

  1. Add transaction support to the service contract. This is required.

  2. Add transaction support to the code that implements the service contract. This is required.

  3. Configure transactions in the implementation code. This is optional.

  4. Enable transactions on the binding. This is required.

Step 1

Create a Service Contract with two Operation Contract

We will create a service contract with two operations .

[OperationContract]
Employee SaveEmployeeData(Employee empData);
[OperationContract]
void SaveEmployeeSalary(Employee empData , EmployeeSalary empSalary );
 
SaveEmployeeData to save Employee Details like ID , Name and Role.
SaveEmployeeSalary to save Employee Details like ID and Salary.
 
Step 2

Add Transaction Support to the Operation Contract

To add transaction support to operation contract , we have to use TransactionFlow attribute .
The TransactionFlow attribute specifies whether the operation supports transactions. There are three possible values for this attribute:

  1. NotAllowed : The operation cannot participate in a transaction. This is the default value for this attribute.
  2. Allowed : The operation will participate in a transaction if the client creates one.
  3. Mandatory : In order to call this operation, the client must create a transaction.  

When the operation has TransactionFlowOption.NotAllowed attribute , the client cannot propagate its transaction to the service. Even if transaction flow is enabled at the binding and the client has a transaction, transaction will not propagate to the service. TransactionFlowOption.NotAllowed is the default TransactionFlowOption value of the TransactionFlow attribute.

TransactionFlowOption.Allowed means the client may or may not have a transaction to propagate to the service. Trying to call a service without a transaction does not throw an exception on the client. With Allowed flow, the client’s transaction always propagates to the service. Once again, the service may or may not use the client’s transaction.

TransactionFlowOption.Mandatory means the client must have a transaction to propagate to the service. Trying to call a service without a transaction throws an exception on the client. With mandatory flow, the client’s transaction always propagates to the service. Once again, the service may or may not use the client’s transaction.
 
[OperationContract]
[TransactionFlow(TransactionFlowOption.Allowed)]
Employee SaveEmployeeData(Employee empData);


[OperationContract]
[TransactionFlow(TransactionFlowOption.Allowed)]
void SaveEmployeeSalary(Employee empData , EmployeeSalary empSalary );

Step 3

Add TransactionScopeRequired Attribute to the Implementation

TransactionScopeRequired Attribute can be set to true or false. To enable transaction set  TransactionScopeRequired attribute to true.

[OperationBehavior(TransactionScopeRequired = true)]
public Employee SaveEmployeeData(Employee empData)
{
SqlConnection objConnection = new SqlConnection(strConnection);
objConnection.Open();
SqlCommand objCommand = new SqlCommand(“INSERT INTO Employee values (‘” + empData.EmpID + “‘,'” + empData.EmpName + “‘,'” + empData.EmpRole + “‘)”, objConnection);
objCommand.ExecuteNonQuery();
objConnection.Close();
return empData;

}
[OperationBehavior(TransactionScopeRequired = true)]
public void SaveEmployeeSalary(Employee empData , EmployeeSalary empSalary )
{
SqlConnection objConnection = new SqlConnection(strConnection);
objConnection.Open();
SqlCommand objCommand = new SqlCommand(“INSERT INTO EmployeeSalary values (‘” + empData.EmpID + “‘,'” + empSalary.EmpSalary + “‘,'” + empSalary.EmpCurrency + “‘)”, objConnection);
objCommand.ExecuteNonQuery();
objConnection.Close();

}

Step 4

Enable Transaction Flow using WCF Service Configuration File

We also need to enable transactions for wsHttpBinding by setting the transactionFlow attribute to true.

<bindings>
<wsHttpBinding>
<binding name=”TransactionalBind” transactionFlow=”true”/>
</wsHttpBinding>
</bindings>

The transaction enabled binding we need to attach with the end point through which our WCF service is exposed.

<endpoint address=”” binding=”wsHttpBinding”
bindingConfiguration=”TransactionalBind” contract=”WcfService1.IService1″>

Step 5

Call the two Operations in One Transaction

Below is Client code to call these operations :
using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew))
{
try
{
ServiceReference1.Service1Client obj = new ServiceReference1.Service1Client();
obj.SaveEmployeeData(empData);
obj.SaveEmployeeSalary(empData , empSalary);
ts.Complete();
}
catch (Exception ex)
{
ts.Dispose();
}
}

WCF Tutorial

Categories: WCF Articles, WCF Tutorial

Leave a Reply