throws javax.transaction.RollbackException,
javax.transaction.SystemException, IllegalStateException
{
TransactionalResource res = null;
XATransactionalResource xatxres = null;
XAResourceTransaction restx = null;
Stack errors = new Stack ();
if ( getStatus () == Status.STATUS_MARKED_ROLLBACK ) {
String msg = "Transaction is already marked for rollback - enlisting more resources is useless.";
Configuration.logWarning ( msg );
throw new javax.transaction.RollbackException ( msg );
}
Enumeration enumm = Configuration.getResources ();
while ( enumm.hasMoreElements () ) {
RecoverableResource rres = (RecoverableResource) enumm
.nextElement ();
if ( rres instanceof XATransactionalResource ) {
xatxres = (XATransactionalResource) rres;
if ( xatxres.usesXAResource ( xares ) )
res = xatxres;
}
}
printMsg ( "enlistResource ( " + xares + " ) with transaction "
+ toString (), Console.INFO );
if ( res == null ) {
if ( autoRegistration_ ) {
synchronized ( Configuration.class ) {
// synchronized to avoid case 61740
// ADDED with new recovery: unknown resources can be tolerated
// by adding a new TemporaryXATransactionalResource
res = new TemporaryXATransactionalResource(xares);
// cf case 61740: check for concurrent additions before this synch block was entered
if ( Configuration.getResource ( res.getName() ) == null ) {
printMsg("constructing new temporary resource "
+ "for unknown XAResource: " + xares, Console.DEBUG);
Configuration.addResource ( res );
}
}
} else {
String msg = "There is no registered resource that can recover the given XAResource instance. " + "\n" +
"Either enable automatic resource registration, or register a corresponding resource.";
Configuration.logWarning ( msg );
throw new javax.transaction.SystemException ( msg );
}
}
// if this xares was suspended then it will still be in the map
XAResourceTransaction active = findXAResourceTransaction ( xares );
if ( active != null ) {
// following violates XA state tables
// and the invariant of the xaresToTxMap table
if ( !active.isXaSuspended () ) {
String msg = "The given XAResource instance is being enlisted a second time without delist in between?";
Configuration.logWarning ( msg );
throw new IllegalStateException ( msg );
}
// note: for suspended XAResources, the lookup MUST SUCCEED
// since the TMRESUME must be called on the SAME XAResource
// INSTANCE, and lookup also works on the instance level
try {
// ADDED: resume should also refresh the xaresource
restx.setXAResource ( xares );
active.xaResume ();
} catch ( XAException xaerr ) {
if ( (XAException.XA_RBBASE <= xaerr.errorCode)
&& (xaerr.errorCode <= XAException.XA_RBEND) )
throw new javax.transaction.RollbackException (
"Transaction was already rolled back inside the back-end resource. Further enlists are useless." );