What a start! We caught a cab to the conference hall. The highway was crowded, the taxi driver took the shoulder on the right handside. Before I forget to mention, the cars here are left hand driven like the USA and are driven on the right handside of the road. The driver banged into a van in front of him. He wasnt that fast and the damage was superficial. While the taxi was stopped, we waited as the meter continued to move. That was odd! Firas went out to take a look first. Then I ventured out. Edgar stayed in, which was wise. Dont step out at a strange place. You cant catch a can out on the highway anyway and there may be a law against walking or standing on the highway. Stay out of trouble. The cab driver radioed or something and another cab driver picked us up. We paid the previous one 5 liras and got in the other one. He was absolutely nuts and drove very very fast and rash and on the shoulder most of the time. In the end, he got caught in a traffic jam on narrow streets, so much for the hurry. We got in late. There werent many people in the hall where Clemens was speaking. Which was nice, we could make contact with him at a personal level, even though he is not that kind of a guy. Clemens even made a rather harsh remark during his dasblog presentation when he switched to Arabic and then going back to English, he said "so that we're not terrorists anymore." I was shocked!
Day 3, session 1, Transaction failure handling in distributed systems by Clemens Vasters
It is surprising that few developers know what they should do about failed transactions, or even whether or how we could know whether the transaction failed or succeeded.
There are two transaction strategies:
two phase commit transactions are also called pessimistic transactions. They consist of
Begin Phase 0
Commit Phase 1
Abort Phase 2
Phase 0 is when we simulate work. Not actual work. In phase 1, we reach agreement on outcome, i.e., everyone is asked by the transaction coordinator if they can do this work. Transactions are not about getting things done fast, but getting things done accurately, even if it takes longer. Something fast but with errors is not acceptable.
Reply Path is given to tbe service to tell it that this is the client and this is where it can give us when it has something for us.
Broker passes EP Reference to the client, and the client can connect to the ultimate service. Similar to COM Marshalling.
Process correlation: MessageID and ReplyTo. Client can correlate based on its hearders. You could use, for instance, a window handle to pass the reply to the appropriate application window, or anything else, for instance a memory reference.
Routing: Gateway wsr:via logical://addressA addressB etc. mapped to EPRs.
Question: What is the differnece between UDDI and WS-Routing
FaultTo: indicates the endpoint to send faults to
If a reply header doesnt exist, the from header can be used. FaultTo is rarely used in Fail Fast situations.
Eventing: How to subscribe to services. Event source (supports a method called Subscribe()) the service that you walk up to,
you can select what set of events you would like to subscribe to based on filter conditions, subscription manager, which may be sending the events to you instead of the event source sending them directly to the client. There is a notion of Renew(),
GetStatus(), Unsubscribe(), all based on EPRs.
WS-Addressing about 5 page standard. Interesting to read.
One way to do the two phase commit by using the [Transaction (TransactionOption.Required)] attributed with the class and [AutoComplete] attribute with the method. Alternative is:
ServiceConfig cfg = new ServiceConfig();
cfg.Transaction = TransactionOption.Required;
//do the transaction stuff
ServiceDomain.Leave(); //returns TransactionStatus which can be used to find
// the status of the transaction
This method uses transactions automatically. Use this if you are using multiple resources such as multiple databases. A user never knows whether the transaction succeeded or not. LocallyOK is a TrnasactionStatus enumeration value that means that locally, things look OK, but no knowledge of remote resources, which does not necessarily guarantee success.
The second technique is imperative transaction.
One solution to not knowing the transaction status is to become part of the transaction itslef using either EnterpriseServices or TransactionScope.
static void Run()
using (TransactionScope tsc = new TransactionScope())
Transaction tx = Transaction.Current;
class TXAbortWorker : IEnlistmentNotification
public void Prepare(Enlistment enlistment)
public void InDoubt(Enlistment enlistment)
throw new Exception("whatever");
public void RollBack(PreparingEnslitment enlistment)
//This is where we can do some work
That was for Whidbey, but here is what we can do even today. We need to use the System.EnterpriseServices.CompensatingResourceManager namespace.
First, we code a compensator
class ESAbortWorker : Compensator
public override bool PrepareRecord (LogRecord rec)
public override bool EndPrepare()
public override bool AbortRecord(LogRecord rec)
//do our abort work here
Then we use a Clerk object inside the try block following ServiceDomain.Enter(); like this:
Transaction strategy number 2 is useful for situations such as bank transfers. Everyone falsely believes that bank transfers use the 2 phase commit, but that is wrong. Banks have something called a clearing account. Every bank has one with every other bank. Bank notification is palced inside a queue which is very veyr reliable, such as the SWIFT system in the USA. The money is debited from the first customers' account and a message is placed inside the queue. On the other side, the system takes the message out of the queue and places the amount in a clearing account. Then, the account is transferred to the destination account. In case something goes wrong, such as the account does not exist, an abort contingent compensator opens another sub transaction in which a "poison" message is placed back in the queue and the money is credited to the account from which it was about to be transferred, and some amount may be deducted from this.
Updating a database record is not a good strategy, especially in these situations. We would be much better off using an insert and having a ValidFrom and a ValidTo field, and marking the old record as invlaid. This way, we have a history. While MSMQ handles failure automatically, we must implement poison list ourselves, where we mark which messages in the queue have failed so that the same transaction does not keep getting retried over and over. Search Clemens' blog for implementation methods of poison lists.
The last session was about a marvelous and very complicated blog application called DasBlog. It is available for free download. Check it out, it is marvelous.
After that session, there was a speakers panel. We sneaked out after lunch. I got some exchange currency, Edgar bought some clothes for his wife. Firas stopped at a StarBucks nearby, but there was no WiFi there, which he learnt later on. Before the speakers panel started, there were speeches by Gurkan and Chigdem. Chigdem talked about MVP. That's about as much as I could get from the slides, everything was in Turkish. One of the slides also mentioned INETA alongwith its URL. I took a snap of that, too.
The speakers panel was nice, people asked questions, mostly in Turkish. They were giving wireless mice to everyone asking the questions. Firas got one, too. It was nice, as Steve, Clemens and Kimberly kept joking all along, too. We met Goksin after that. I made a call back home from his cell phone and he reimbursed our expenses to us and gave some cash for INETA activities and some INETA MEA writing pads. We went back straight to the hotel, dropped our stuff and got down to StarBucks to check email and stuff.