PRB: DTC Phase 0: DTC Proxy Holds Reference on the notifyAsync Sink Object Even After Phase0Done (234614)



The information in this article applies to:

  • Microsoft COM+ 1.0
  • Microsoft COM+ 1.5

This article was previously published under Q234614

SYMPTOMS

The Phase0 Enlistment object releases the Phase0 Notification object only when the Phase0 Enlistment object is being destroyed. But the sink object is not needed after Phase0Done.

If you implement the sink to reference the enlistment object and only destroy it in the destructor, a circular reference problem might occur.

MORE INFORMATION

The Phase Zero (phase0) notification mechanism is provided by Phase0 Enlistment objects and Phase0 Notification objects. These objects implement the ITransactionPhase0EnlistmentAsync Interface and ITransactionPhase0NotifyAsync Interface, respectively. The former is implemented by the Microsoft Distributed Transaction Coordinator proxy while the latter is implemented by the application that needs to participate in Phase0 (Phase0 participant). Both interfaces are exchanged as sinks when a Phase0 Enlistment object is created.

Other enlistment objects, such as Voter, release the sink as soon as the proxy is done with the sink object (after VoterRequestDone). But the Phase0Enlistment object releases the Phase0NotifyAsync object only when the Phase0EnlistmentAsync object is being destroyed.

This might cause a circular reference problem. For example, consider the following scenario.
Class A
{
  ~A() { if (m_pB) m_pB->release();};
  B *m_pB;
}

Class B
{
  ~B() { if (m_pA) m_pA->release();};
  A *m_pA;
}
				
In this scenario, the destructor will never get called because the two objects are holding reference to each other.

The workaround is to break the link between the Enlistment and Notification objects by releasing the Enlistment object explicitly after calling Phase0Done.

Modification Type:MajorLast Reviewed:2/20/2002
Keywords:kbDSupport kbDTC kbprb kbTransaction KB234614