Distributed Transactions in WCF services – Part 3

Enabling distributed transaction propagation in WCF services is a tricky task and several factors and parameters need to be considered. Previous posts showed you that by default distributed transactions aren’t supported even if you enclose your operations you want to consume in a single “TransactionScope”. This post is the last of these series and will show you how to enable transaction support in WCF services. I assume you have already read Part 1 and Part 2 of the series, since I am gonna continue from where we stopped the last time. Let’s start.

First we need to allow the transaction to flow from the client to the service. This is done by modifying the binding configuration in the Web.config file. We have been using the wsHttpBinding in our service project, a binding that supports transactions. What we haven’t done already, is to tell that binding to enable “TransactionFlow”. Do that, by adding a “transactionFlow” attribute to the binding and setting it’s value to true.

<system.serviceModel>
    <serviceHostingEnvironment >
      <serviceActivations>
        <add factory="System.ServiceModel.Activation.ServiceHostFactory"
        relativeAddress="./NorthwindService.svc"
        service="NorthwindService.NorthwindService"/>
      </serviceActivations>
    </serviceHostingEnvironment>
    <bindings>
      <wsHttpBinding>
        <binding name="transactionalWsHttpBinding"
        transactionFlow="true" receiveTimeout="00:10:00"
        sendTimeout="00:10:00" openTimeout="00:10:00"
        closeTimeout="00:10:00" />
      </wsHttpBinding>
    </bindings>
    <services>
      <service name="NorthwindService.NorthwindService">
        <endpoint address="" binding="wsHttpBinding" contract="NorthwindService.INorthwindService"
                  bindingConfiguration="transactionalWsHttpBinding">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information,
          set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
          <!-- To receive exception details in faults for debugging purposes,
          set the value below to true.  Set to false before deployment
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

At this time, we have configure our service binding to allow transactions flow from client to service. Next, we need to enable our service operation to opt in to participate in a distributed transaction. Open the “INorthwindService.cs” file where our service contract relies and add a “[TransactionFlow(TransactionFlowOption.Allowed)]” expression above the UpdateProduct operation.

[ServiceContract]
    public interface INorthwindService
    {
        [OperationContract]
        [FaultContract(typeof(ProductFault))]
        Product GetProduct(int id);
        [OperationContract]
        [FaultContract(typeof(ProductFault))]
        [TransactionFlow(TransactionFlowOption.Allowed)]
        bool UpdateProduct(ref Product product, ref string message);
    }

This will allow a transaction to be propagated to the UpdateProduct operation. Open the service implementation class “NorthwindService” under the NorthwindService.cs file and add a “TransactionScopeRequired” behavior attribute to the UpdateProduct implementation. This will ensure that this operation will always be executed under a transaction, either propagated by the client or not.

 [OperationBehavior(TransactionScopeRequired = true)]
        public bool UpdateProduct(ref Product product, ref string message)
// implementation code omitted -  you can find it from the previous posts

Rebuild the Service Project so that service hosted in IIS will be updated with the latest changes we have made. In the ASP.NET NorthwindClient project we created in the previous post, right click the “Reference.svcmap” under the App_WebReferences folder and select “Update service reference..”. This will regenerate the service proxy adding a “TransactionFlow” attribute equals to true in the Web.config file of the client’s project.

<system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="WSHttpBinding_INorthwindService" transactionFlow="true" />
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://developer-pc/NorthwindService/NorthwindService.svc"
        binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_INorthwindService"
        contract="NorthwindServiceProxy.INorthwindService" name="WSHttpBinding_INorthwindService">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>

There are few important things left to do before we test again if distributed transactions are supported in our WCF service. The component that is actually responsible for coordinating the distributed transaction propagated by the client, is the “Microsoft Distributed Transaction Coordinator” (MDTC). If this component isn’t configured properly, the transaction will still fail. In other words, when the client propagates the transaction calling (in our specific client project) two updates simultaneously, that component is activated in order to manage the transaction. Make sure you make MDTC configurations as follow:

1. In Windows, click start and find the “run” command window. Type “dcomcnfg” and click enter. This will open the “Componet Services” window. Expand “Component Services”, then “My computers”. Right click “My computer” and select properties. Click the MDTC tab and make sure the “Use local coordinator” checkbox is checked.

MDTC1

2. Close “My computer properties” window, expand “My computer”, then expand “Distributed Transaction Coordinator” and right click the “Local DTC” item. Select properties and make sure you set the “Security” properties as follow:

MDTC2

3. The last thing left is to configure Windows Firewall allow MDTC communicate though it. Open “Allow a program or feature through Windows Firewall” from Control Panel and make sure “Distributed Transaction Coordinator” is on the list and checked as follow. If you can’t find “Distributed Transaction Coordinator” on the list, add the program from “windows\system32\msdtc.exe” location.

MDTC3

Finally we are ready to test our new configurations and propagate a transaction from the client’s project to the WCF service. I will not show if the WCF service work under valid Product Unit prices as we did in previous posts (you can test it if you want), but instead I will go straight forward and test the service by setting on purpose a negative value for the second Unit Price. If you remember, doing so till now, resulted the first product’s Unit Price to be updated despite the fact that the second UpdateProduct operation failed. If Distributed Transaction is supported now, the first product’s Unit Price update will roll back and nothing will actually change in a database level. Let’s test it. Set the client’s project as the default and Run without debugging. I entered “20” and “21” for product’s Ids. In my database, UnitPrice of product with Id:20 is 84 and UnitPrice of the second product is 13. I will enter to change first product’s unit price to 85 and second’s to -10. You can see that second’s UpdateProduct operation will fail and what we expect this time, is since these operations are called through a “TransactionScope” (look Part 2 of series) the first UpdateProduct result will have to roll back.

MDTC4

Click “Update Price” button. You will see that first product’s unit price was updated (don’t be so sure) and second’s UpdateProduct operation failed.

MDTC5

Click again the “Get Product Details” button with the same Ids.

MDTC6

We finally did it. First product’s update rolled back keeping it’s UnitPrice to 84. I hope these series helped you understand how to enable Distributed Transaction support in WCF services.

Advertisements


Categories: ASP.NET, WCF

Tags: , ,

5 replies

  1. Excellent demo, I would like to know how to handle transactions without using IIS, I have a WCF service on a host windows form, I handle it as a service but my question arises on how to handle the transactions, could give me a guidance for this?, Thanks.

  2. Thanks…Very nice…

  3. thanks… vey nice article…

  4. True it is a very nice demo..

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Chara Plessa

The purpose of this blog is to broaden my education, promote experimentation and enhance my professional development. Albert Einstein once said that “If you can’t explain it simply, you don’t understand it well enough” and I strongly believe him!

chsakell's Blog

Anything around ASP.NET MVC,WEB API, WCF, Entity Framework & AngularJS

Kumikoro

A Front End Developer's Blog

Muhammad Hassan

Full Stack developer with expertise in ASP.NET | MVC | WebAPI | Advanced Javascript | AngularJS | Angular2 | C# | ES6 | SQL | TypeScript | HTML5 | NodeJS, NUCES-FAST CS grad, MS candidate @LUMS, EX-Adjunct Faculty @NUCES-FAST, seasonal blogger & open-source contributor. Seattle, WA

Software Engineering

Web development

IEvangelist

.NET, ASP.NET, C#, MVC, TypeScript, AngularJS

leastprivilege.com

Dominick Baier on Identity & Access Control

Happy DotNetting

In Love with Technology

Knoldus

Knols of experience to your advantage

knowshnet

Search - Read - Request - Share

Rahul's space

Learn, Share and Grow with me !

Dhananjay Kumar

Developer Evangelist @Infragistics | MVP @Microsoft |

Journey to SQL Authority with Pinal Dave

SQL, SQL Server, MySQL, Big Data and NoSQL

Conficient Blog

Random bits of tech from @conficient

Code! Code! Code!

SOLID & KISS

Code Wala

Designing and coding

Microsoft Mentalist

A way to start with Microsoft Technologies

Tony Sneed's Blog

A glimpse into the lives of Tony & Zuzana Sneed

Sriramjithendra Nidumolu

Personal Notes of Sriramjithendra

%d bloggers like this: