Problem:

  • Product Name: VisiTransact
  • Product Version: 7.0 and later
  • Product Component: POA Managed Transactions
  • Platform/OS Version: All

When the same PMT attributes are used to CORBA objects with call back, the call back will hang up until a CORBA::TIMEOUT exception is raised and the whole transaction is rolled back.
 
Figure-1 describes the flow of CORBA calls.

  1. When Client Process invokes Object1::print() hosted on Process A, the installed PM interceptor’s preinvoke() will be called implicitly.
  2. The preinvoke() will call DTP X/A’s xa_start() to inform a resource manager that an application may do work on behalf of a transaction branch, using a globally unique XID (based on gtrid and bqual taken together).
  3. After preinvoke(), the servant’s Object1::print() will be implicitly called, where another remote invocation is made on Object2::print() hosted on Process B. At this point the xa_start() for Object1::print() haven’t been dissociated with the thread yet using the xa_end() from transaction branch.
  4. In turn, Object2::print() calls back Object3::print() hosted on Process A.
  5. The hang up occurs when the PMT interceptor’s preinvoke() for Object3::print() will once again call the xa_start() using the same XID (step #9 in Figure 1).
  6. Unless the xa_end() for the Object1::print() has been called in time, Object1::print()’s timeout will kick in throwing CORBA::TIME_OUT exception and the VisiTransact will raise the CORBA::TRANSACTION_ROLLEDBACK exception for the whole transaction.ā€ƒ

Figure-1

The Oracle log (Figure-2) shows that another xa_start() has been called using the same XID. Per DTP: XA specification,page 52, ā€œIf another thread is accessing the calling thread’s resource manager for the same branch, xa_start() may block and wait for the active thread to release control of the branch (via xa_end()).ā€

In this case, the Object1::print() already have a pending xa_start() (line# 156) and Object3::print() invokes another xa_start() (line# 324) with the same XID.

Figure-2

The following is the normal use case scenario:

  1. The PMT interceptor’s preinvoke() will be implicitly called. Within which, it calls the xa_start();
  2. After preinvoke(), the servant’s method will be invoked;
  3. After the servant’s method returns, the postinvoke() will be implicitly called. Within which, it calls the xa_end();


 

Resolution:

The installed interceptor for PMT is a VisiBroker design and the blocking / waiting for active thread to release control of the branch is a DTP XA specification constraint -- a necessary constraint to protect the DB transaction.

If all the objects (i.e. Object1::print() and Object3::print()) are configured to use the same XA resource configuration (in effect, the global transaction / PMT attributes are the same) and a call back is implemented, a hang up will occur in the xa_start() during the call back.

The possible resolutions are, but not limited to:

  1. Avoid a call back to objects with the same XA resource configuration (as specified in vbroker.its.xadesc property).
  2. Make the call back function to be a non-PMT by setting the VISTransactions::PMTAttrSeq::mode to VISTransactions::PMT_NotSupported.