@Override
    public void lazyEnlist(ManagedConnection mc) throws ResourceException {
        final boolean isTraceOn = TraceComponent.isAnyTracingEnabled();
        if (isTraceOn && tc.isEntryEnabled()) {
            Tr.entry(this, tc, "lazyEnlist");
        }

        /*
         * Get the mcw from the mc to mcw hash map.
         */
        MCWrapper mcWrapper = null;

        if (mc != null) {
            mcWrapper = (MCWrapper) _pm.getMCWFromMctoMCWMap(mc);

            if (mcWrapper == null) {
                if (isTraceOn && tc.isDebugEnabled()) {
                    String errorString = "The " + mc + " could not be matched with a mcWrapper for pool manager " + _pm.hashCode() + " Dumping the mc to mcWrapper table "
                                         + _pm.getMCtoMCWMapToString();
                    Tr.debug(this, tc, errorString);
                }
                String errorString = "The ManagedConnection from resource " + _pm.gConfigProps.cfName + " could not be enlisted with the current transaction.";
                Tr.error(tc, "FAILED_TO_ASSOCIATE_CONNECTION_J2CA0292", _pm.gConfigProps.cfName);
                ResourceException e = new ResourceException(errorString);
                throw e;
            }
            if (isTraceOn && tc.isDebugEnabled()) {
                Tr.debug(this, tc, "Used mc " + mc + " to find mcWrapper " + mcWrapper);
            }
        } else {
            if (isTraceOn && tc.isDebugEnabled()) {
                String errorString = "The managed connection is null, we can not find the matching managed connection wrapper in connection pool " + _pm.hashCode();
                Tr.debug(this, tc, errorString);
            }
            String errorString = "The Connection Manager lazyEnlist method requires a non-null ManagedConnection parameter.";
            Tr.error(tc, "FAILED_TO_ENLIST_CONNECTION_J2CA0293", _pm.gConfigProps.cfName);
            ResourceException e = new ResourceException(errorString);
            throw e;
        }

        /*
         * Moved and modified code from ConnectionEventListener interactionPending to this method.
         * Removed the call to interactionPending.
         */

        if (!_pm.gConfigProps.isDynamicEnlistmentSupported()) {
            if (isTraceOn && tc.isEntryEnabled()) {
                Tr.exit(this, tc, "lazyEnlist", "lazyEnlist Not Supported.  Nothing to do. Returning.");
            }
            return;
        }

        //
        // The LocalTransactionStarted event for local transaction connections is analogous to the
        //  InteractionPending event for xa transaction connections.  JMS's usage of ManagedSessions
        //  is very dependent on the ability to use these two events for properly enlisting their
        //  unshared connections.  When a ManagedSession is first created, it is done under an LTC.
        //  When that LTC ends, some partial cleanup is done on the MCWrapper, but it is not put
        //  back into the pool because the unshared connection handle is still active.  One of the
        //  items that gets cleaned up is the coordinator within the MCWrapper.  This makes sense
        //  since the LTC has ended.  But, when it is determined by JMS that it's time to get
        //  enlisted in the current transaction, a null coordinator causes all kinds of problems
        //  (reference the string of defects that have attempted to correct this situation).  The
        //  solution determined seems to be the right one.  In both localTransactionStarted
        //  and interactionPending methods, we need to check if the MCWrapper coordinator is null and
        //  if it is null, then go out to the TM and get it updated.
        //
        // Note that this special null coordinator processing is due to the SmartHandle support
        //  utilized by JMS and RRA.  Without smart handles, the coordinator would have gotten
        //  re-initialized during the handle re-association logic.
        //
        //
        // And, now that we have cleaned up the null ConnectionManager reference
        //  when processing the exception case we can allow the
        //  resetting of the coordinator for the transaction timeout scenario as
        //  well.  They will get an enlistment failure exception
        //  which should be consistent with the expected result.
        //

        UOWCoordinator uowCoord = mcWrapper.getUOWCoordinator();
        boolean uowCoordNotSet = false;
        if (uowCoord == null) {
            uowCoordNotSet = true;
            uowCoord = mcWrapper.updateUOWCoordinator();
            if (isTraceOn && tc.isDebugEnabled()) {
                Tr.debug(this, tc, "uowCoord was null, updating it to current coordinator");
            }
        }

        if (isTraceOn && tc.isDebugEnabled()) {
            Tr.debug(this, tc, "Coordinator in effect: " + uowCoord);
        }

        if (uowCoord != null) {
            if (uowCoord.isGlobal()) {
                //NOTE: global transactions will be enlisted here only if the RA supports deferred enlistment.
                //  Local trans will be enlisted during the localTransactionStarted event on the
                //  connectionEventListner.

                TranWrapper wrapper = null;
                try {
                    // If deferred enlistment is supported by the RA, then enlistment in a global tran
                    // will happen here. Otherwise, enlistment is done in the allocate() method of the CM.
                    wrapper = mcWrapper.getCurrentTranWrapper();
                    if (wrapper == null) {
                        Tr.error(tc, "NULL_TRAN_WRAPPER_J2CA0057");
                        // Bad state.  Throw a Runtime exception.
                        if (isTraceOn && tc.isEntryEnabled()) {
                            Tr.exit(this, tc, "lazyEnlist", "No TranWrapper found.");
                        }
                        RuntimeException rte = new IllegalStateException("lazyEnlist: No TranWrapper found.");
                        throw rte;
                    }
                } catch (Exception e) {
                    // clean everything up!
                    com.ibm.ws.ffdc.FFDCFilter.processException(e, "com.ibm.ejs.j2c.ConnectionManager.lazyEnlist", "1307", this);
                    Tr.error(tc, "ENLIST_FAILED_J2CA0074", new Object[] { "lazyEnlist", e, _pm.gConfigProps.cfName });
                    try {
                        mcWrapper.markStale();
                        mcWrapper.releaseToPoolManager();
                    } catch (Exception e2) {
                        com.ibm.ws.ffdc.FFDCFilter.processException(e2, "com.ibm.ejs.j2c.ConnectionManager.lazyEnlist", "1316", this);
                    }
                    // Note that the enlist call will set RollbackOnly as appropriate.
                    // Throw a ResourceException to indicate enlistment failure to the ResourceAdapter
                    ResourceException re = new ResourceException(e.getMessage());
                    re.initCause(e);
                    throw re;
                }

                wrapper.enlist();

            } else {
                /*
                 * For a local transaction, if the uowCoord was not already set,
                 * we need to set it to null in the mcWrapper.
                 */
                if (uowCoordNotSet) {
                    mcWrapper.resetCoordinator();
                }
            }
        } else {
            // No transaction context.
            //
            // Now that we are requiring a transaction context to execute, we will go ahead with logging an
            //   error message and throwing an exception in this case.  There is no "cleanup" to do on the
            //   connection since that was taken care of by other processing (probably during the transaction
            //   timeout processing).
            //
            // If we get to this point (missing transaction context even after attempting to update the
            //  transaction context above), then this is an error whether we are supporting
            //  "no transaction mode" or not.  The RA is asking for us to enlist in a transaction.  If there
            //  is none, then we should log the message and throw the exception regardless.
            //
            //   We decided to loosen the requirement for a transaction context when lazyEnlist is
            //   invoked.  We will now enlist, if a transaction context exists.  Otherwise, we will
            //   conditionally log a message and just return.  This processing will now be consistent
            //   with non-deferred enlistment processing.
            //
            //   The conditional can be triggered by setting the logMissingTranContext property on
            //   an individual datasource or connection factory basis.  The other half of the conditional
            //   allows for non-transactional access to resources for JMS access from EJB 1.1
            //   modules.
            if (isTraceOn && tc.isDebugEnabled()) {
                Tr.debug(this, tc, "Transaction context does NOT exist");
            }
            if (_pm.gConfigProps.logMissingTranContext) {
                Tr.warning(tc, "MISSING_TRANSACTION_CONTEXT_J2CA0075", "lazyEnlist");
            }
        }

        if (isTraceOn && tc.isEntryEnabled()) {
            Tr.exit(this, tc, "lazyEnlist");
        }
    }
@ Override public void lazyEnlist ( ManagedConnection mc ) throws ResourceException { final boolean isTraceOn = TraceComponent . isAnyTracingEnabled ( ) ; if ( isTraceOn && tc . isEntryEnabled ( ) ) { Tr . entry ( this , tc , "lazyEnlist" ) ; } MCWrapper mcWrapper = null ; if ( mc != null ) { mcWrapper = ( MCWrapper ) _pm . getMCWFromMctoMCWMap ( mc ) ; if ( mcWrapper == null ) { if ( isTraceOn && tc . isDebugEnabled ( ) ) { String errorString = "The " + mc + " could not be matched with a mcWrapper for pool manager " + _pm . hashCode ( ) + " Dumping the mc to mcWrapper table " + _pm . getMCtoMCWMapToString ( ) ; Tr . debug ( this , tc , errorString ) ; } String errorString = "The ManagedConnection from resource " + _pm . gConfigProps . cfName + " could not be enlisted with the current transaction." ; Tr . error ( tc , "FAILED_TO_ASSOCIATE_CONNECTION_J2CA0292" , _pm . gConfigProps . cfName ) ; ResourceException e = new ResourceException ( errorString ) ; throw e ; } if ( isTraceOn && tc . isDebugEnabled ( ) ) { Tr . debug ( this , tc , "Used mc " + mc + " to find mcWrapper " + mcWrapper ) ; } } else { if ( isTraceOn && tc . isDebugEnabled ( ) ) { String errorString = "The managed connection is null, we can not find the matching managed connection wrapper in connection pool " + _pm . hashCode ( ) ; Tr . debug ( this , tc , errorString ) ; } String errorString = "The Connection Manager lazyEnlist method requires a non-null ManagedConnection parameter." ; Tr . error ( tc , "FAILED_TO_ENLIST_CONNECTION_J2CA0293" , _pm . gConfigProps . cfName ) ; ResourceException e = new ResourceException ( errorString ) ; throw e ; } if ( ! _pm . gConfigProps . isDynamicEnlistmentSupported ( ) ) { if ( isTraceOn && tc . isEntryEnabled ( ) ) { Tr . exit ( this , tc , "lazyEnlist" , "lazyEnlist Not Supported.  Nothing to do. Returning." ) ; } return ; } UOWCoordinator uowCoord = mcWrapper . getUOWCoordinator ( ) ; boolean uowCoordNotSet = false ; if ( uowCoord == null ) { uowCoordNotSet = true ; uowCoord = mcWrapper . updateUOWCoordinator ( ) ; if ( isTraceOn && tc . isDebugEnabled ( ) ) { Tr . debug ( this , tc , "uowCoord was null, updating it to current coordinator" ) ; } } if ( isTraceOn && tc . isDebugEnabled ( ) ) { Tr . debug ( this , tc , "Coordinator in effect: " + uowCoord ) ; } if ( uowCoord != null ) { if ( uowCoord . isGlobal ( ) ) { TranWrapper wrapper = null ; try { wrapper = mcWrapper . getCurrentTranWrapper ( ) ; if ( wrapper == null ) { Tr . error ( tc , "NULL_TRAN_WRAPPER_J2CA0057" ) ; if ( isTraceOn && tc . isEntryEnabled ( ) ) { Tr . exit ( this , tc , "lazyEnlist" , "No TranWrapper found." ) ; } RuntimeException rte = new IllegalStateException ( "lazyEnlist: No TranWrapper found." ) ; throw rte ; } } catch ( Exception e ) { com . ibm . ws . ffdc . FFDCFilter . processException ( e , "com.ibm.ejs.j2c.ConnectionManager.lazyEnlist" , "1307" , this ) ; Tr . error ( tc , "ENLIST_FAILED_J2CA0074" , new Object [ ] { "lazyEnlist" , e , _pm . gConfigProps . cfName } ) ; try { mcWrapper . markStale ( ) ; mcWrapper . releaseToPoolManager ( ) ; } catch ( Exception e2 ) { com . ibm . ws . ffdc . FFDCFilter . processException ( e2 , "com.ibm.ejs.j2c.ConnectionManager.lazyEnlist" , "1316" , this ) ; } ResourceException re = new ResourceException ( e . getMessage ( ) ) ; re . initCause ( e ) ; throw re ; } wrapper . enlist ( ) ; } else { if ( uowCoordNotSet ) { mcWrapper . resetCoordinator ( ) ; } } } else { if ( isTraceOn && tc . isDebugEnabled ( ) ) { Tr . debug ( this , tc , "Transaction context does NOT exist" ) ; } if ( _pm . gConfigProps . logMissingTranContext ) { Tr . warning ( tc , "MISSING_TRANSACTION_CONTEXT_J2CA0075" , "lazyEnlist" ) ; } } if ( isTraceOn && tc . isEntryEnabled ( ) ) { Tr . exit ( this , tc , "lazyEnlist" ) ; } }
Lazy Transaction Enlistment Optimization (deferred enlistment, CEL.interactionPending())

Note for code updates:

This is deferred enlistment for 6.0 and later. If code changes are needed for this
method, the same changes may be needed for CEL.interactionPending(). New function type changes should only
be undated in this method.

We do not want to add new function in CEL.interactionPending(). RAs using CEL.interactionPending(), should move to
this method. CEL.interactionPending() is deprecated starting in v6.0.