IDG Contributor Network: How to work with transactional WCF services

Datetime:2016-08-23 04:35:05          Topic: WCF           Share

WCF (Windows Communication Foundation) is a secure, reliable, and scalable messaging platform for developing services in .Net.

A transaction is a set of statements that are executed by following the ACID principles (ACID stands for Atomic, Consistent, Isolated, and Durable operations). When one of the operations in the transaction block fails, the entire transaction is aborted, i.e., the entire transaction fails. WCF provides support for distributed transactional operations. You can leverage the TransactionScope class present in the System.Transactions namespace for efficient transaction management when working in .Net.

Implementing WCF transactions

In this section we will explore how we can create transactional WCF services. To get started, create two WCF services. You can also create another project (a console or a web project) to test your services. Once the two WCF services have been created, you should decorate the operation contracts that would be part of the transaction with the TransactionFlow attribute. This is needed to enable transaction support.

This attribute accepts the TransactionFlowOption enum as a parameter. The TransactionFlowOption can have one of the following values:

  • TransactionFlowOption.Allowed
  • TransactionFlowOption.Mandatory
  • TransactionFlowOption.NotAllowed

When working with WCF, you first need to create a service contract and then define the service operations or operation contracts in it. You have many different types of contracts in WCF -- service contracts, data contracts, fault contracts, message contracts and operation contracts. In this example we will use service contracts and operation contracts as the other ones can be optional. A ServiceContract is used to specify the operations that are available for the service client to consume. In this section we will create two service contracts for the two WCF services we are using.

The following code snippet illustrates how you can configure the TransactionFlow attribute in your WCF service contract to provide transactional support. Note that you need to do the same in the other operation contracts (that are part of the transaction) as well.

[ServiceContract]

public interface IOrderService

{

    [OperationContract]

    [TransactionFlow(TransactionFlowOption.Allowed  )]

    void AddOrder(Order order);

}

Note that each service contract should have one or more operation contracts to define the operations that are exposed over the wire. An operation contract is used to define the signature of the service method and also the transaction flow, direction of the service operation and optionally, any fault contract(s) that may be associated.

Here's how the IOrderHeaderService interface (service contract) would look like.

[ServiceContract]

public interface IOrderHeaderService

{

    [OperationContract]

    [TransactionFlow(TransactionFlowOption.Allowed  )]

    void AddOrderHeader(OrderHeader orderHeader);

}

Next, you should ensure that your service method is decorated with TransactionScopeRequired using the OperationBehavior attribute. In essence, you should set the TransactionScopeRequired property to "true" in the operation contract as shown in the code snippet below. The statement TransactionScopeRequired=true is used to specify that the service operation needs a transaction scope to be executed.

[OperationBehavior(TransactionScopeRequired = true)]

public void AddOrder(Order order)

{

   // Write code here to add an order record to the database

}

The same change applies to the other service operation as well.

[OperationBehavior(TransactionScopeRequired = true)]

public void AddOrderHeader(OrderHeader orderHeader)

{

   // Write code here to add an order header record to the database

}

The next step is to configure your service configuration file to enable transaction flow. Assuming that you are using wsHttpBinding, here's how you can configure your WCF service to provide transaction flow support.

<bindings>

<wsHttpBinding>

<binding name="IDGTransaction" transactionFlow="true"/>

<reliableSession enabled ="true"/>

</wsHttpBinding>

</bindings>

Note that when working with transactional WCF services you can optionally specify reliable messaging to dilute the possibility of aborted transactions due to communication failures. You should also configure your WCF service endpoints accordingly to leverage the binding we just defined.

<endpoint address="" binding="wsHttpBinding"

                bindingConfiguration="IDGTransactional" contract="IDGServices.IOrderService">

You would now need to take advantage of the TransactionScope class present in the System.Transactions namespace to call your services from within one transaction scope. Typically you can use this class to implement transaction scope for handling interdependent transactions and resolve concurrency conflicts when working with ADO.Net.

try

{

  using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.RequiresNew))

  {

    // Write code here to call the service methods of your services here

    transactionScope.Complete();

  }

}

catch

{

  //Write code here to handle exceptions

}

And that's all you need to do. You can now execute your application and test your transactional services.

This article is published as part of the IDG Contributor Network.Want to Join?





About List