Dirty WCF: Generating and propagating a transaction in a forwarding service.

Well, as I have explained before, the TransactedReceiveScope activity creates a serializable transaction that causes blocks. I have used a tag to modify this behaviour and create a ReadCommitted transaction, but it doesn’t work under certain situations.

Now I have tried a different and much dirtier approach. The overall idea is to receive any message through a basicHTTPBinding, create a readcommitted TX, insert the TX header in the message and send it through a transactional binding to the Workflow client.

How? Well, first the interface that accepts any message:


    [ServiceContract]
    public interface IWcfTxCreatorService
    {
          //gets any message
          [OperationContract(Name="ProcessMessage",Action="*",ReplyAction="*")] 
          [TransactionFlow(TransactionFlowOption.Allowed)]
          Message ProcessMessage(Message message);
    }

And now the important part, the service implementation.


    [ServiceBehavior(TransactionIsolationLevel = System.Transactions.IsolationLevel.ReadCommitted,
      TransactionTimeout = "00:10:00", MaxItemsInObjectGraph = 2147483647)]
    public class WcfTxCreatorService : IWcfTxCreatorService
    {
       
        [OperationBehavior(TransactionScopeRequired = true)]
        public Message ProcessMessage(Message requestMessage)
        {
            //this sends any message, without formating, to the typed client.
            ChannelFactory<IWcfTxCreatorService> factory = new ChannelFactory<IWcfTxCreatorService>("client");

            try
            {
                IWcfTxCreatorService proxy = factory.CreateChannel();

                IClientChannel clientChannel = proxy as IClientChannel;

                var xmlWithoutTransation = requestMessage.ToString();


                //add tx header if it doesn't exists
                if (!xmlWithoutTransation.Contains("OleTxTransaction"))
                {
                    var tranToken = TransactionInterop.GetTransmitterPropagationToken(System.Transactions.Transaction.Current);

                    requestMessage.Headers.Add(new TxHeader(tranToken, 60000));
                    
                }
                
                        
                var action = requestMessage.Headers.Action;
                var to = requestMessage.Headers.To;

                var requestMessageFinal = fromBasicHttpToNetPipeMessage(requestMessage, factory.Endpoint.Address.ToString(), action);
                Message responseMessage = proxy.ProcessMessage(requestMessageFinal);


                action = responseMessage.Headers.Action;
                var responseMessageFinal = fromNetPipeToBasicHttpMessage(action, responseMessage);

                return responseMessageFinal;
            }
            finally
            {
                try
                {
                    factory.Close();
                }
                catch { }
            }
        }

To use the service the client has to generate a proxy pointing to the final typed service, but set the client endpoint address to this “TXforwarding” service and set the client endpoint of the forwarding to the final typed one.

Of course it is a total adhoc dirty solution, but maybe the code can be helpful for someone. Here it is.

Enjoy!

Advertisements

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

%d bloggers like this: