The Problem Solver

Tell me and I will forget
Show me and I will remember
Involve me and I will understand
- Confucius -

Google Ads

This Blog

Syndication

Search

Tags

News





  • View Maurice De Beijer's profile on LinkedIn

Community

Email Notifications

Explore

Archives

Flowing transaction into a workflow using WF4

One of the things that wasn’t possible in Windows Workflow Foundation 3 was flowing transaction over a WCF service request into a workflow. We could have transactions on the client, we could have transactions on the server but they would not be able to cooperate.

Fortunately that is one the problems that Windows Workflow Foundation 4 solves for us. [:)]

 

In WF4 we can use the ReceiveAndSendreply template to configure a workflow as a service and accept WCF calls. That works just fine but doesn’t allow for transactions. If we want to use transactions we need to add the TransactedReceiveScope to the workflow. Move the ReceiveRequest activity into the Request part and the SendResponse activity into the Body part. Don’t forget the last part because leaving the SendResponse below the TransactedReceiveScope means things will not work and the error message will be less that helpful [:(]

 

image

This is enough to make all work done during the message receive part of a transaction. To show what is happening with transactions I am using the following code to record and return the transactional status:

using System.Text;
using System.Transactions;
 
public class TransactionReport
{
    public static string GetReport()
    {
        var sb = new StringBuilder();
 
        if (Transaction.Current == null)
        {
            sb.Append("No transaction");
        }
        else
        {
            sb.AppendFormat("TransactionInformation\n");
            sb.AppendFormat("\tLocalIdentifier {0}\n", Transaction.Current.TransactionInformation.LocalIdentifier);
            sb.AppendFormat("\tDistributedIdentifier {0}\n", Transaction.Current.TransactionInformation.DistributedIdentifier);
            sb.AppendFormat("\tStatus {0}\n", Transaction.Current.TransactionInformation.Status);
            sb.AppendFormat("\tIsolationLevel {0}\n", Transaction.Current.IsolationLevel);
        }
 
        return sb.ToString();
    }
}

 

Adding a console application with a service reference with the following code:

using System;
using Client.ServiceReference1;
 
namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            var proxy = new ServiceClient();
            var result = proxy.PostData();
 
            Console.WriteLine(result);
 
 
            Console.ReadLine();
        }
    }
}

Produces the following output:

image

No big surprises there. The only thing I am missing is the ability to control the IsolationLevel which seems to be fixed at Serializable.

 

 

Flowing transactions from the client

The first step we need to take for client transactions to flow to the service is do the service call inside of a transaction using this client code:

using System;
using System.Transactions;
using Client.ServiceReference1;
 
namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
 
            using (var tx = new TransactionScope())
            {
                Console.WriteLine(TransactionReport.GetReport());
 
                var proxy = new ServiceClient();
                var result = proxy.PostData();
 
                Console.WriteLine(result);
 
                Console.WriteLine(TransactionReport.GetReport());
            }
 
            Console.ReadLine();
        }
    }
}

If we run the code now we get the following output:

image

The transaction is there on the client but DistributedIdentifier is still empty so the transaction doesn’t flow to the service yet.

 

Before transactions will flow we need to do two things. First of all we need a WCF binding that can flow transactions. So far we have been using the BasicHttpBinding, the default for an HTTP endpoint in the .NET 4 default configuration, which doesn’t support transactions. So we need to switch to something like WSHttpBinding that does. Next we need to enable transaction flow because it is disabled by default. All of this can be done by adding a little extra configuration to the web.config file.

<bindings>
  <wsHttpBinding>
    <binding transactionFlow="true"/>
  </wsHttpBinding>
</bindings>
<services>
  <service name="Service1">
    <endpoint address=""
              binding="wsHttpBinding"
              contract="IService" />
  </service>
</services>

With this in place all we need to do is update the client service reference and transactions will flow from the client to the service.

image

 

Keep in mind that flowing transactions across a network boundary is a very powerful but also a very dangerous concept. You might be letting someone else, from a different organization, place locks on your database. So make sure you understand the implications of flowing transactions before you open up a whole can of worms!

 

Nice [:)]

 

Enjoy!

TheProblemSolver
DotNetEvents

Published Mon, Dec 21 2009 17:43 by Maurice
Filed under: , , , ,

Comments

# re: Flowing transaction into a workflow using WF4@ Tuesday, February 09, 2010 4:04 AM

Suppose the workflow service is calling WCF ado.net data service, will this transaction flow from client to workflow service to ado.net data service

by kanchan

# re: Flowing transaction into a workflow using WF4@ Tuesday, February 09, 2010 4:04 AM

Suppose the workflow service is calling WCF ado.net data service, will this transaction flow from client to workflow service to ado.net data service

by kanchan

# re: Flowing transaction into a workflow using WF4@ Tuesday, February 09, 2010 4:24 AM

@Kanchan,

Provided that the WCF binding is configured to flow transactions it will.

by Maurice

# re: Flowing transaction into a workflow using WF4@ Wednesday, March 03, 2010 5:17 AM

I use this to define a transactional scope in within I can call transactional services, but if I throw an exception in the workflow, the transaction isn't rollback.

I need help, please.

by raullm

# re: Flowing transaction into a workflow using WF4@ Monday, March 08, 2010 11:37 AM

@raullm,

If the client doesn't catch and handle the error in its transaction this should be rolled back and that should trigger the service transaction to rollback.

by Maurice