Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

WCF FAQ Part 5 – Transactions

4.50/5 (9 votes)
9 Aug 2009CPOL7 min read 92.1K   1.3K  
In this article, we will understand the WCF transaction protocol, the two phases in WCF transactions, transaction options, and finally simple samples for WCF transactions.

Table of contents

Introduction and goal

This is my fifth WCF FAQ article. This article is completely dedicated to WCF transactions. In this article, we will understand the WCF transaction protocol, the two phases in WCF transactions, transaction options, and finally simple samples for WCF transactions.

WCF is new to me, I am not in a position to read this article

If you are completely new to WCF, then this article will not suffice, my suggestion would be to go through some of the below articles for basics:

  • WCF FAQ Part 1: This is a 20 question FAQ for beginners which explains the basic concepts of WCF like End Points, contracts, and bindings. It also discusses the various hosting methodologies of WCF services. The article finally talks about bindings and one way operations in WCF: http://www.codeproject.com/KB/aspnet/WCF.aspx.
  • WCF FAQ Part 2: This FAQ covers 10 questions which talk about concepts like duplex contracts, hosting WCF on different protocols, MSMQ bindings, transaction isolation levels, and two way communication. The article finally talks about two queues: volatile and dead letter queue. http://www.codeproject.com/KB/aspnet/WCFPart2.aspx.
  • WCF FAQ Part 3 (Security FAQ ): In this article, we will start with transport and message security understanding. We will then see simple code samples of how to implement transport and message security using WsHTTP bindings. We will also see the difference between BasicHttpBinding and WsHttpBinding with the help of a simple source code. WCF security is a huge topic by itself, but we are sure with this article, you will get a quick start of how to go about WCF security: WCFFAQPart3.aspx.
  • WCF Tracing FAQ Part 4: In this article, we will look at how we can trace and debug information in WCF services. There are some ready made trace listeners provided by WCF. The base of these ready-made trace listeners is the .NET trace listener. So we will first understand the basic concept of trace listener and then go through the ready made trace listeners provided by WCF: WCFTracingFAQ.aspx.

Which protocol is used to handle transactions in WCF?

WCF follows WS-* specifications. So it uses the WS-Atomic protocol to manage transactions across WCF services. So you can have different WCF services hosted on different computers and they all can run under one transaction unit. The best part of the WS-Atomic protocol is that in one transaction you can have heterogeneous WCF services developed in different platforms. In other words, you can have Java and .NET Web Services running under one transaction. WS-* specifications are globally approved standards to create services.

Image 1

What are the two different kinds of phases in WCF transactions?

WCF transactions follow two phase commit. So there are two phases: the prepare phase and the commit phase. All co-ordination of transactions is done by the transaction manager.

Image 2

In prepare phase, the transaction manager checks whether all entities are prepared to commit. In commit phase, the actual commit starts. You can think about the prepare phase as a check saying that all entities are ready to commit and in the commit phase we do the actual work.

Where does the transaction manager reside?

The transaction manager resides at the client computer which initiates the transaction.

Can you explain in depth how the prepare and commit phases work?

Let’s consider three computers as shown in the below figure. The client consuming the WCF service resides in computer A while computers B and C have the WCF services. The transaction is initiated from the computer A. So as we said previously, there are two phases: the prepare phase and the commit phase. In prepare phase, computer A sends messages to all WCF services saying, are they ready to commit? Once all WCF services respond saying that they are ready for commit, it starts the second phase. In the second phase, the WCF client issues a commit command. All the WCF services start execution and once they are done, they revert back saying they have committed. When all the WCF services revert saying they have committed, the transaction is marked as successful.

Image 3

Can we implement transactions in one-way WCF service calls?

As we have already seen in the previous sections, WCF transactions are two-phase commits. In other words, for every commit, you need to get a confirmation response saying if the commit is successful. In one-way WCF services, we do not get any response back, so WCF transactions are not possible with one way WCF service calls.

Can we see a simple WCF example of transactions using a SQL Server database?

To enable a WCF transaction is a six step procedure. So let’s create two WCF services and let’s try to call them in one transaction.

Step 1: Create two WCF services

The first step is to create two WCF service projects which will participate in a transaction. In both of these WCF services, we will do database transactions and we will try to understand how a WCF transaction unifies them. We have also created a web application with the name WCFTransactions which will consume both the services in one transaction scope.

Image 4

Step 2: Attribute interface methods with TransactionFlow

In both the WCF services we will create a method called UpdateData which will do an insert into the database. So the first thing is to create the interface class with the ServiceContract attribute and the method UpdateData with the OperationContract attribute. In order to enable the transaction in the UpdateData method, we need to attribute it with TransactionFlow and we have specified that transactions are allowed for this method using the TransactionFlowOption.Allowed enum.

C#
[ServiceContract]
public interface IService1
{
    [OperationContract]
    [TransactionFlow(TransactionFlowOption.Allowed)]
    void UpdateData();
}

Step 3: Attribute the implementation with ‘TransactionScopeRequired’

The third step is to attribute the implementation of the WCF services with TransactionScopeRequired as true. Below is the code snippet which has a simple database inserting function, i.e., UpdateData, which is attributed by the TransactionScopeRequired attribute.

C#
[OperationBehavior(TransactionScopeRequired = true)]
public void UpdateData()
{
    SqlConnection objConnection = new SqlConnection(strConnection);
    objConnection.Open();
    SqlCommand objCommand = new SqlCommand("insert into " + 
      "Customer(CustomerName,CustomerCode) values('sss','sss')",
      objConnection);
    objCommand.ExecuteNonQuery();
    objConnection.Close();
}

Step 4: Enable the transaction flow using the WCF service config file

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

XML
<bindings>
<wsHttpBinding>
<binding name="TransactionalBind" transactionFlow="true"/>
</wsHttpBinding>
</bindings>

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

XML
<endpoint address="" binding="wsHttpBinding" 
   bindingConfiguration="TransactionalBind" contract="WcfService1.IService1">

Step 5: Call the two services in one transaction

Now that we are done with our server side transaction enablement, it’s time to call the above two services in one transaction. We need to use the TransactionScope object to group the above two WCF services in one transaction. To commit all the WCF transactions, we call the Complete method of the Transactionscope object. To rollback, we need to call the Dispose method.

C#
using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew))
{
    try
    {
        // Call your webservice transactions here
        ts.Complete();
    }
    catch (Exception ex)
    {
        ts.Dispose();
    }
}

Below is the complete code snippet in which we have grouped both the WCF transactions in one scope:

C#
using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew))
{
    try
    {
        ServiceReference1.Service1Client obj = new ServiceReference1.Service1Client();
        obj.UpdateData();
        ServiceReference2.Service1Client obj1 = new ServiceReference2.Service1Client();
        obj1.UpdateData();
        ts.Complete();
    }
    catch (Exception ex)
    {
        ts.Dispose();
    }
}

Step 6: Test your transaction work

It’s time to test if the transactions really work. We are calling two services and both of these services are doing an insert. After the first WCF service call, we are forcing an exception. In other words, the data insert of the first WCF service should revert back. If you check the database records, you will see no records are inserted by the WCF service.

Image 5

What are the different transaction options?

In the previous code, we used TransactionFlowOption. We can specify transactions in three ways in WCF:

TransactionFlowOption.NotAllowed

This is the default option. Using this option, no transaction will be propagated across the binding. If a client attempts to call the WCF service in a transaction, it will be ignored for this option.

TransactionFlowOption.Allowed

This option specifies that the client can call this WCF service in a transaction. It’s not compulsory that the service needs to be called in a transaction. You can call without the transaction also.

TransactionFlowOption.Mandatory

This option specifies that the client must call the WCF service in a transaction mode. If the WCF service is called without a transaction, a FaultException will be raised.

Source code

You can find the source code for this article here.

For further reading do watch the below interview preparation videos and step by step video series.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)