When transaction promotion goes "bad"

We already know the benefits of promotable transactions. They are all about performance, being very fast and lightweight.

But then you get into situations where you know for sure that you are going to talk to a second resource manager, so you know you will get to a distributed transaction anyway. Or, the resource managers out there that support promotable transactions might have limitations when you put them into edge cases. But you really want to use that edge case and it doesn't work.

Well, one solution is to "turn off" promotion and force a distributed transaction from the beginning such that all the resource managers involved will follow the classic route of enlisting in the transaction. We don't actually provide a flag today in System.Transactions to "turn off" promotable transactions, but you can achieve it by forcing the transaction to be a distributed transaction before you open any resource manager connection.

The way you do it in code is by calling:

            TransactionInterop.GetTransmitterPropagationToken(tx);

Where tx is the transaction you want to promote.

If you are using TrasactionScope similar to:

 using(TransactionScope ts = new TransactionScope())
{
    connection.Open();
    // do the work on the first connection
    connection2.Open();
    // do the rest of the work
    ts.Complete();
}

Then the code with the workaround should be:

 using(TransactionScope ts = new TransactionScope();)
{
    TransactionInterop.GetTransmitterPropagationToken(Transaction.Current);
    connection.Open();
    // do the work on the first connection
    connection2.Open();
    // do the rest of the work
    ts.Complete();
}

With time, resource managers will get better. But today, you might find this <trick> useful.