Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX

By submitting your information, you agree that devx.com may send you DevX offers via email, phone and text message, as well as email offers about other products and services that DevX believes may be of interest to you. DevX will process your information in accordance with the Quinstreet Privacy Policy.


Getting Started with Windows Communication Foundation Transactions

Transactions aren't just for database applications any more. Using the unified transaction system in the Windows Communication Foundation, you can create transactable services not only for database applications, but for messaging, workflow, and other types of applications as well.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

he previous two articles in this series provided an overview of the Windows Communication Foundation (WCF, formerly code-named Indigo) programming model, service addressing, binding and contracts, and a discussion of how to secure Windows Communication Foundation services using the built-in attribution method.

If you haven't already done so, it would be a good idea to go through those articles to get up and running quickly with WCF. In particular, if you are having any trouble getting a development environment installed and working, you'll find that those articles explain the process.

The pillars of WCF are intended to help you build secure, reliable, and transactable services for .NET. In this article, you will build on the code from the previous two articles to create your first transactable service.

Transactions in WCF
Transactions ensure that a group of related operations occur as a single atomic unit. In other words, every operation in the unit must either all succeed or all fail. WCF provides a centralized transaction system that you can use to handle transaction operations for you. In the past, transaction logic was commonly available as a standard way to handle database transactions (remember BeginTrans and CommitTrans in VB?), but there was no standard way to perform non-database transactions. WCF aims to solve this with a single unified transaction system that you can use for database, communications, or other transactable actions.

The WCF programming model makes transactions very easy to use. You group operations into a transaction scope. This scope defines the atom of a transaction. The following pseudo code demonstrates this:

Using(TransactionScope theScope = new TransactionScope()) { Service1.submitRequest(myRequest); Service2.submitRequest(myOtherRequest); Service3.submitRequest(myFinalRequest); theScope.Complete(); }

Building Your First Transactable Service
To get started, you first need a service that is transactable. This means that you are willing to let your service participate in a client-initiated transaction on your contracted operations. You will specify (using attributes and configuration files) how this transaction will behave. After building the service, you'll step through the process of building a client that uses a transaction scope when calling the service. If you have set up Visual Studio.NET as outlined in the WCF security article, you should be able to get up and running very quickly.

To get started, create a new Web Site in Visual Studio.NET. Select the IndigoService project type, and call it TService. Your screen should look like Figure 1.

Figure 1. Creating a New Indigo Service: After selecting the Indigo Service project type and giving it the name TService, your screen will look like this.
Visual Studio will create a default service for you with an interface called IMyService, and a service class called MyService. You'll find the service class code in the Service.cs file in the App_Code subfolder. Replace the code in this file with the code shown in Listing 1. You'll also need to add a reference to the System.Transactions namespace for the code to work correctly when you compile it.

Note that the code for the transactable Web service is identical to the original "temperatures" Web service from the primer tutorial except for the new attributes that describe it as being transactable.

At the interface level, when the methods are defined, the OperationContract is attributed with a [TransactionFlow] attribute. This notifies the runtime of how to respond in a transaction situation when operating on the OperationContract in question. The valid values are Allowed whereby the operation may or may not be used in a transaction; NotAllowed where it is never to be used in a transaction, and Required where it must only be used within a transaction scope.

At the service level, the [ServiceBehavior] attribute specifies the transaction properties, using the TransactionIsolationLevel property. Ideally transactions should exhibit the four key properties of being atomic, consistent, isolated and durable, described by the acronym ACID. However, keeping them fully isolated from one another can result in resource locks being held longer than necessary, which can cause lock contention, degrading performance, or even deadlock situations, where different transactions each need locks held by the other transaction to complete. Setting the isolation level lets you choose the degree of isolation most compatible with other applications. You set the isolation level by setting the IsolationLevel property value to the ServiceBehavior's TransactionIsolationLevel property value. In Listing 1, the IsolationLevel is set to ReadCommited, meaning that volatile data cannot be read in the transaction, but can be modified. For a full exploration of the different isolation level property values you can use, refer to the documentation for the System..Transactions.IsolationLevel enumeration. Note that there's also a System.Data.IsolationLevel enumeration, so if you refer to the System.Data namespace in your code then you should fully qualify the IsolationLevel to avoid confusion.

Finally, Listing 1 defines the transaction behavior for the Web method within the service using the [OperationBehavior] attribute, which has its TransactionScope property set to true. This TransactionScope setting indicates that the operation must be called within a scope (as will be demonstrated within the client). The TransactionAutoComplete property is also set to true to indicate that the transaction will be flagged as complete when the method finishes executing. If the TransactionAutoComplete property were set to false, then you would have to call the OperationContext.Current.SetTransactionComplete() method to set the correct completion of the transaction manually; otherwise the transaction would flag it as failed.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date