public final void end ( int flag ) throws XAException { if ( tc . isEntryEnabled ( ) ) Tr . entry ( tc , "end" , new Object [ ] { _resource , Util . printFlag ( flag ) , printState ( _state ) } ) ; if ( tcSummary . isDebugEnabled ( ) ) Tr . debug ( tcSummary , "xa_end" , new Object [ ] { this , "flags = " + Util . printFlag ( flag ) } ) ; int newstate ; int rc = - 1 ; // not an XA RC switch ( flag ) { case XAResource . TMSUCCESS : // xa_end(SUCCESS) on a suspended branch can be ended without a resumed start if ( _state == ACTIVE || _state == SUSPENDED ) { newstate = IDLE ; } else // NOT_ASSOCIATED || ROLLBACK_ONLY || IDLE || FAILED { if ( tc . isEntryEnabled ( ) ) Tr . exit ( tc , "end" ) ; return ; } break ; case XAResource . TMFAIL : // If the branch has already been marked rollback only then we do not need to // re-issue xa_end as we will get another round of xa_rb* flows. // If its idle, we dont need to issue xa_end if ( _state == ROLLBACK_ONLY || _state == IDLE || _state == FAILED ) { if ( tc . isEntryEnabled ( ) ) Tr . exit ( tc , "end" ) ; return ; } newstate = ROLLBACK_ONLY ; break ; case XAResource . TMSUSPEND : if ( ! _supportSuspend ) { if ( tc . isEventEnabled ( ) ) Tr . event ( tc , "TMSUSPEND is not supported." ) ; throw new XAException ( XAException . XAER_INVAL ) ; } else if ( _state == FAILED || _state == IDLE ) { if ( tc . isEventEnabled ( ) ) Tr . event ( tc , "TMSUSPEND in invalid state." ) ; throw new XAException ( XAException . XAER_PROTO ) ; } else if ( _state != ACTIVE ) { if ( tc . isEntryEnabled ( ) ) Tr . exit ( tc , "end" ) ; return ; } newstate = SUSPENDED ; break ; default : Tr . warning ( tc , "WTRN0023_INVALID_XAEND_FLAG" , Util . printFlag ( flag ) ) ; throw new XAException ( XAException . XAER_INVAL ) ; } try { _resource . end ( _xid , flag ) ; rc = XAResource . XA_OK ; // // update XAResource's state // _state = newstate ; } catch ( XAException xae ) { processXAException ( "end" , xae ) ; rc = xae . errorCode ; if ( xae . errorCode >= XAException . XA_RBBASE && xae . errorCode <= XAException . XA_RBEND ) _state = ROLLBACK_ONLY ; else _state = FAILED ; throw xae ; } catch ( Throwable t ) { _state = FAILED ; processThrowable ( "end" , t ) ; } finally { if ( tc . isEntryEnabled ( ) ) Tr . exit ( tc , "end" ) ; if ( tcSummary . isDebugEnabled ( ) ) Tr . debug ( tcSummary , "xa_end result:" , XAReturnCodeHelper . convertXACode ( rc ) ) ; } }
Terminate the association of the XAResource with this transaction .