2PC using MSDTC behaves differently on one/two computers

Hi,

I have the following problem...
I start a transaction within one processproc1 (by creating a new TransactionScope) and enlist a custom IEnlistmentNotification implementation. Then, using .NET remoting, I call a method on a remote object (another processproc2) and pass the current Transaction to it. This method creates a new (nested) TransactionScope using the passed Transaction and enlists another custom IEnlistmentNotification implementation.
After completing bot scopes I can observe different behavior depending on whether the 2 processes run on a single computer or on two different computers.
(1) on one comp: The Prepare() method of theproc1 is called and in parallel Prepare() ofproc2 is called as well. (this is also my desired behavior)
(2) on two comps: Only Prepare() ofproc1 is called, but Prepare() ofproc2 is called only after the first one finishes.

Coresponding code:
PROC1:
using (scope = new TransactionScope() )
{
//Create an enlistment object
myEnlistmentClass1 myEnlistment = new myEnlistmentClass1();
//Enlist on the current transaction with the enlistment object
Transaction.Current.EnlistVolatile(myEnlistment, EnlistmentOptions.None);

//Perform transactional work here.
object remoteObj = Activator.GetObject(
typeof(RemoteProcess2),
"tcp://192.168.0.101:22223/RemoteProcess2.rem"); //change IP depending on home of proc2
RemoteProcess2 remoteProc2 = (RemoteProcess2)remoteObj;

remoteProc2.Execute(Transaction.Current);

scope.Complete();
}

PROC2:
public int Execute(Transaction txn)
{
using (TransactionScope scope = new TransactionScope(txn))
{
myEnlistmentClass2 myEnlistment = new myEnlistmentClass2();
Transaction.Current.EnlistVolatile(myEnlistment, EnlistmentOptions.None);
scope.Complete();
}
}

The classes myEnlistmentClass1 and 2 define a very simple implementations of the IEnlistmentNotification interfaces. The Prepare() method blocks for 10 seconds to better observe the described behavior using:
System.Threading.Thread.Sleep(10000);

Can anyone please explain this behavior? The two processes on one mashine define 2 app domains (or not?), so even in this case the MSDTC should got involved! Behaves the DTC differently in these cases?

thanks for any suggestions
Juraj

[2889 byte] By [JurajOprsal] at [2007-12-30]
# 1
Yes, there is a different behavior in these cases. Namely, in the second case, there are two DTC processes involved: the one on the source machine, and the one on the destination machine. I am thinking that this is probably an optimization, due to the higher cost of communicating with the second enlistment (goes through the DTC on the second machine). I will try to find out more details on this...
cornel-MSFT at 2007-9-5 > top of Msdn Tech,Software Development for Windows Vista,Transactions Programming...
# 2
I've tried to create a local repro, and I was able to duplicate the same behavior. I will try to investigate why this happens, and will come back with more info.
cornel-MSFT at 2007-9-5 > top of Msdn Tech,Software Development for Windows Vista,Transactions Programming...
# 3
BTW, what OSs are installed on the two machines?
cornel-MSFT at 2007-9-5 > top of Msdn Tech,Software Development for Windows Vista,Transactions Programming...
# 4

After some investigation, it turns out that this behavior is by design. As I was explaining previously, in the 2 machine case, there are 2 DTCs involved. More precisely, the DTC on the source machine is the root, and the DTC on the destination machine is subordinate to the first DTC (it has a durable enlistment with the 1st DTC).

The picture now is like this:

- The 1st DTC has a volatile enlistment (created by app), and a durable enlistment (the subordinate DTC)

- The 2nd DTC has only a volatile enlistment (created by 2nd app).

Because of the Single-Phase Commit optimization (supported by DTC - http://msdn2.microsoft.com/en-us/library/ms229980(VS.80).aspx), the 1st DTC will have to first hear from all its volatile enlistments (only one here) before starting a Single-Phase Commit with its durable enlistment (the 2nd DTC). As a result, we see the current behavior for 2-machine transaction propagation.

I guess the only issue here is that this behavior could apparently lead to an inter-enlisment DOS attack. However, since enlistments in the same transaction implicitly trust each other (w.r.t the transaction), this apparent DOS doesn’t really pose any threat.

- Cornel M.

cornel-MSFT at 2007-9-5 > top of Msdn Tech,Software Development for Windows Vista,Transactions Programming...
# 5

BTW, if you really want to achieve the concurrent 'Prepare' for the 2-machine case, you could simply create one more (superfluous) durable enlistment with the 1st DTC. The SPC optimization will cease to apply in that case ;-)

cornel-MSFT at 2007-9-5 > top of Msdn Tech,Software Development for Windows Vista,Transactions Programming...
# 6
Thank you, I appreciate it a lot!
Juraj
JurajOprsal at 2007-9-5 > top of Msdn Tech,Software Development for Windows Vista,Transactions Programming...

Software Development for Windows Vista

Site Classified