Wednesday 31 July 2013

WCF Transactions in easy 5 Steps with Example

Hi Friends,

In this article, I will first explain what is transaction and what are the properties of transaction and then I will try to explain how we can implement transactions in WCF service. So we will create WCF services which do database transactions and then check the transaction. I will first understand the steps how to enable transactions in WCF services. At the end of the article, I will try to force an error and see how the transaction is rolled back after the error.


What is Transactions?

A transaction is a unit of work that is performed against a database. Transactions are units or sequences of work accomplished in a logical order, whether in a manual fashion by a user or automatically by some sort of a database program.

Properties of Transactions:

Transactions have the following four standard properties, usually referred to by the acronym ACID:
·         Atomicity: ensures that all operations within the work unit are completed successfully; otherwise, the transaction is aborted at the point of failure, and previous operations are rolled back to their former state.
·         Consistency: ensures that the database properly changes states upon a successfully committed transaction.
·         Isolation: enables transactions to operate independently of and transparent to each other.
·         Durability: ensures that the result or effect of a committed transaction persists in case of a system failure.


There are easy 5 steps for setting transactions in WCF

Step 1:  For service operation Setting.

Create a WCF Service for Account and Enable TransactionFlowOption Mandatory
There are 3 modes for transaction flow option

•    Allowed    Transaction may be flowed.
•    Mandatory    Transaction must be flowed.
•    NotAllowed    A transaction should not be flowed. This is the default value.


In the below service I creates one Service contract IAccountService and two Service operations Deposit and Withdraw for particular Account ID a

[ServiceContract]
     public  interface IAccountService
    {
        [OperationContract]
        [TransactionFlow(TransactionFlowOption.Mandatory)]
        [FaultContract(typeof(ErrorInfo))]
         void Deposit(int AccountId, decimal amount);

        [OperationContract]
        [TransactionFlow(TransactionFlowOption.Mandatory)]
        [FaultContract(typeof(ErrorInfo))]
         void WithDraw(int AccountId, decimal amount);

    }


Step 2: In Operational Behavior Setting

In Operation Behavior we have to enable TransactionScopeRequired = true and TransactionAutoComplete=true

·         TransactionScopeRequired: indicates whether the method requires a transaction scope for its execution.
·         TransactionAutoComplete: indicates whether to automatically complete the current transaction scope if no unhandled exceptions occur.

[ServiceBehavior(TransactionIsolationLevel=System.Transactions.IsolationLevel.Serializable)]
   public class AccountService:IAccountService
    {
        [OperationBehavior(TransactionScopeRequired=true,TransactionAutoComplete=true)]
        public void Deposit(int AccountId, decimal amount)
        {
//Your Code Here
 }

[OperationBehavior(TransactionScopeRequired=true,TransactionAutoComplete=true)]
        public void withDraw(int AccountId, decimal amount)
        {
//Your Code Here

}
    }




Step 3: Enable Transaction Flow using WCF Service Config File

Binding - There are only few bindings in WCF that can support transaction, these are NetTcpBinding, NetNamedPipeBinding, WSHttpBinding, WSDualHttpBinding, and WSFederationHttpBinding. So, in order to configure transaction, one has to make a choice out of such bindings. Though these bindings do have transaction support but by default it is disabled, so one has to make them enabled.

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

  <bindings>
            <wsHttpBinding>
                <binding name="WsHttpConfig" transactionFlow="true">
                    <reliableSession enabled="true" />
                </binding>
            </wsHttpBinding>
  </bindings>


Also give this setting to bindingConfiguration

<services>
            <service behaviorConfiguration="MetaBehavior" name="WCFClassLibrary.AccountService">
                <endpoint address="BankService" binding="wsHttpBinding" bindingConfiguration="WsHttpConfig"
                    name="BankService_http" contract="WCFClassLibrary.IAccountService" />
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:8055" />
                    </baseAddresses>
                </host>
            </service>
        </services>


Step 4: On the Client Side Use TrasactionScope

We need to use TrasactionScope Attribute on to the client side for Transaction.
Create the TrasactionScope to execute the commands, guaranteeing that both commands can commit or roll back as a single unit of work.

using (TransactionScope t = new TransactionScope())
                {
                    AccountService.AccountServiceClient proxy = new AccountService.AccountServiceClient();
                    proxy.Deposit(1, 2000);
                    proxy.WithDraw(2, 200);
                    t.Complete();
                    proxy.Close();
                }

Step 5: Check the Transactions is Working or not

In the Withdraw method we are checking that if the Account balance is less than 500 then we are throwing the fault exception and Transaction is rollback

                if (accountBalance - amount < 500)

                    throw new FaultException<ErrorInfo>(new ErrorInfo() { ErrorCode = "200", ErrorDescription = "InSufficient Balance found" }, "InSufficient Balance found");

In this way you can test the Transactions is working or not on the client side.

I have attached Code snippet for that. Please download this.


Happy Programming!!

If you have any query mail me to Sujeet.bhujbal@gmail.com     


Regards

Sujeet Bhujbal

------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------



No comments:

Post a Comment