Distributed Transactions with Indigo and WS-AT

This evening I played with Indigo and WS-AT, to see if it works, in order to use it in a project of a customer of mine.

First of all the good news: it works :-) as it did in PDC03 bits! Great job guys!
Second news: it's not so easy to manage all the stuff, but at least it works fine.

I developed two different services, working on a couple of SQL Server 2005 database.
One service is exposed using a net.tcp (netProfileTcpBinding) binding. The other is exposed using http (wsProfileBinding), self-hosted.

Both are used by a third party client, that covers the transactional work with a TransactionScope.

Here is a sample of one of the two transactional services:

namespace ServiceOne
{
 [ServiceContract(
  FormatMode=ContractFormatMode.XmlFormatter,
  Namespace="
http://schemas.devleap.com/Services/OrderService1",
  Style=ServiceOperationStyle.DocumentBare,
  Use=ServiceOperationBindingUse.Literal)]
 [BindingRequirements(
  TransactionFlowRequirements = RequirementsMode.Require)]

 public interface ITxServiceOne
 {
  [OperationContract(
   Action="urn:saveOrder1")]
  Int32 SaveOrder(OrdersLibrary.Order order);
 }
 
 [ServiceBehavior(
  AllowConcurrentTransactions=true,
  TransactionIsolationLevel=IsolationLevel.ReadCommitted)]
 public class TxServiceOne: ITxServiceOne
 {
  [OperationBehaviorAttribute(
   AutoEnlistTransaction = true,
   AutoCompleteTransaction = true)]
  public int SaveOrder(OrdersLibrary.Order order)
  {
   OrdersLibrary.OrderBiz ob = new OrdersLibrary.OrderBiz();
   return (ob.SaveOrder(order));
  }
 }
}

Take care of BindingRequirements and OperationBehavior attributes, respectively on the service contract and on the operation implementation.

Here is the service side configuration file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns="
http://schemas.microsoft.com/.NetConfiguration/v2.0">
 <appSettings>
  <add key="SqlConnectionString" value="..."/>
 </appSettings>
 <system.serviceModel>
  <services>
   <service
    serviceType="ServiceOne.TxServiceOne, ServiceOne"
    behaviorConfiguration="txServiceBehavior">
    <endpoint
     contractType="ServiceOne.ITxServiceOne, ServiceOne"
     address="
http://localhost:35000/TxServiceOne.svc"
     bindingConfiguration="txBinding"
     bindingSectionName="wsProfileBinding" />
   </service>
  </services>
  <bindings>
   <wsProfileBinding>
    <binding configurationName="txBinding" flowTransactions="Required" />
   </wsProfileBinding>
  </bindings>
  <behaviors>
   <behavior
    configurationName="txServiceBehavior"
    returnUnknownExceptionsAsFaults="true" >
   </behavior>
  </behaviors>
 </system.serviceModel>
</configuration>


Pay attention to the behaviors section, where I declare to manage any exception as a Fault.
Take a look also at the custom binding configuration, defined in order to require transactions.
The other service is very similar to the first one.

Lastly here is the main part of client code:

schemas.devleap.com.EntitiesOrder.Order order = new schemas.devleap.com.EntitiesOrder.Order();
order.id = 10;
order.description = "Order 10";

TransactionOptions options = new TransactionOptions();
options.IsolationLevel = IsolationLevel.ReadCommitted;
options.Timeout = TimeSpan.FromSeconds(30);

using(TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, options))
{
 TxServiceOneProxy svcOne = null;
 TxServiceTwoProxy svcTwo = null;
 
 try
 {
  // External transactional activity
  svcOne = new TxServiceOneProxy();
  Console.WriteLine("Service One: {0}", svcOne.SaveOrder(order));

  try
  {
   // Internal transactional activity
   svcTwo = new TxServiceTwoProxy();
   Console.WriteLine("Service Two: {0}", svcTwo.SaveOrder(order));

   // Transaction commit, in case of success
   scope.Complete();
   
  }
  finally
  {
   // Internal channel closing
   svcTwo.Close();
  }
 }
 finally
 {
  // External channel closing
  svcOne.Close();
 }
}

Here you can find all the code of the demo solution I developed to test WS-AT support in Indigo.

In order to make it work, don't forget to download this fix (published on 21/06/2005):

http://www.microsoft.com/downloads/details.aspx?familyid=32187993-4736-4a06-97c7-1282b67e3137&displaylang=en

I hope you'll enjoy your Indigo transactional experience :-) !

4 Comments

  • In my opinion, if you need to flow a transaction between two services then your services aren't really services in that their autonomy is compromised. It might be better to model them as components within the same service.



    While I think that Indigo is a valuable technology, I'm worried that it will make it too easy to implement a poor design.

  • Udi,

    thanks for your comment, I agree and disagree with you at the same time.

    First of all I agree with your statement about services autonomy, from a SOA point of view of course.

    As all we know, from a SOA perspective, services should be autonomous and if you coordinate them within a distributed transaction, they are not so autonomous.

    On the other side consider that SOA isn't just wrapping a bounch of components with a service and in some situations you should need to coordinate many different SOA services published by different systems, autonomous by themself, but linked in some businnes activites. That's why orchestration tools like BizTalk Server are so usefull.



    I think you should also keep in mind that Indigo in not ASMX v.3, Indigo is a communication infrastructure that will merge and join different technologies like: ASMX, .NET Remointg, WSE, COM+, MSMQ.

    When designing components you need transaction sometime, don't you? So if you're designing a component, to be published using http or net.tcp or something else, and you need it to be transactional: Indigo allows you to do that. Where is the problem? I think that's a poor design to not consider the capability to handle transactions, in case of need, just because you're using SOAP as your message formatting when publishing components.



    I don't like to be a prisoner of a technology. I like to design my solutions empowered by it.



    Last but not least: Indigo supports distributed transactions greatly, in a way that is compliant with a common specification (made by Microsoft, IBM and BEA). So I'm absolutely happy and not worried about the possibility to easily empower my components with features that are wide interoperable.

  • Hi.

    The post is insteresting, as interesting and promising (and WAY COOOL!) is Indigo.

    What puzzles me is the sentence &quot;in order to use it in a project of a customer of mine&quot;... two possibilities:

    1) you love risk

    2) Indigo is ready for prime time.

    I am a long-time developer of MS technologies, and I've experienced that these things are often immature even when they are officially released...So, are you really willing to use in a production environment a really new, albeit cool, technology as Indigo? I'd like too, I need it badly, but I (still) do not trust it. maybe I am wrong...

    m

  • Marco,

    I didn't said when my customer's project needs to be released ... and it's not tomorrow, neither next month :-) ... may be late next year (2006) ... so it's a long way.



    Anyway Indigo seems to be already stable enough in many situations.

Comments have been disabled for this content.