docs: @Override
      public void localTransactionStarted(ConnectionEvent event) {
  
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
              Tr.entry(this, tc, "localTransactionStarted");
          }
  
          if (event.getId() == ConnectionEvent.LOCAL_TRANSACTION_STARTED) {
  
              //
              // 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.
              //
              // In addition, we have determined that the check for involvedInTransaction() is not necessary
              //  (and causes problems for the scenario described just previous).  Since the getCurrentTranWrapper()
              //  already checks for a valid state setting before returning, we can just rely on that method to
              //  do the proper checking instead of calling the involvedInTransaction() method.
              //
              UOWCoordinator uowCoordinator = mcWrapper.getUOWCoordinator();
  
              if (uowCoordinator == null) {
                  uowCoordinator = mcWrapper.updateUOWCoordinator();
                  if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                      Tr.debug(this, tc, "uowCoord was null, updating it to current coordinator");
                  }
              }
  
              // if the coordinator is still null, then we are running with NO transaction
              //  context on the thread.  This case currently needs to be supported because
              //  servlets can spin their own threads which would not have context.
              // Note: it is very rare that users do this.  All other occurances are
              //  considered to be an error.
              if (uowCoordinator == null) {
                  if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
                      Tr.exit(this, tc, "localTransactionStarted", "no transaction context, return without enlisting");
                  }
                  return;
              }
  
              /*
               * We know we are in a transaction but we need to verify that it is not a global transaction
               * before continuing.
               */
              if (tc.isDebugEnabled() && uowCoordinator.isGlobal()) {
                  IllegalStateException ise = new IllegalStateException("Illegal attempt to start a local transaction within a global (user) transaction");
                  Tr.debug(this, tc, "ILLEGAL_USE_OF_LOCAL_TRANSACTION_J2CA0295", ise);
              }
  
              /*
               * The ManagedConnection should be associated with a transaction. And, if it's not,
               * the getCurrentTranWrapper() method will detect the situation and throw an
               * exception.
               *
               * enlist() the ManagedConnection from the transaction.
               */
  
              try {
                  mcWrapper.getCurrentTranWrapper().enlist();
              } catch (ResourceException e) {
                  /*
                   * // Can't enlist, something went wrong.
                   * // Destroy the connection(s) so it can't cause any future problems.
                   * try {
                   * mcWrapper.markStale();
                   * mcWrapper.releaseToPoolManager();
                   * }
                   * catch (Exception ex) {
                   * // Nothing to do here. PoolManager has already logged it.
                   * // Since we are in cleanup mode, we will not surface a Runtime exception to the ResourceAdapter
                   * FFDCFilter.processException(ex, "com.ibm.ejs.j2c.ConnectionEventListener.localTransactionStarted", "473", this);
                   * if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                   * Tr.debug(this, tc, "localTransactionStarted: Error when trying to enlist " + mcWrapper.getPoolManager().getPmiName() +
                   * " caught exception, but will continue processing: ", ex);
                   * }
                   * }
                   */
  
                  FFDCFilter.processException(e, "com.ibm.ejs.j2c.ConnectionEventListener.localTransactionStarted", "481", this);
                  // add datasource name to message
                  Tr.error(tc, "ENLIST_FAILED_J2CA0074", "localTransactionStarted", e, mcWrapper.gConfigProps.cfName);
                  // Moved event.getSource() inside of catch block for performance reasons
                  ManagedConnection mc = null;
                  try {
                      mc = (ManagedConnection) event.getSource();
                  } catch (ClassCastException cce) {
                      Tr.error(tc, "GET_SOURCE_CLASS_CAST_EXCP_J2CA0098", cce);
                      throw new IllegalStateException("ClassCastException occurred attempting to cast event.getSource to ManagedConnection");
                  }
                  ConnectionEvent errorEvent = new ConnectionEvent(mc, ConnectionEvent.CONNECTION_ERROR_OCCURRED);
                  this.connectionErrorOccurred(errorEvent);
  
                  RuntimeException rte = new IllegalStateException(e.getMessage());
                  throw rte;
              }
          } else {
              // Connection Event passed in doesn't match the method called.
              // This should never happen unless there is an error in the ResourceAdapter.
              processBadEvent("localTransactionStarted", ConnectionEvent.LOCAL_TRANSACTION_STARTED, event);
          }
  
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
              Tr.exit(this, tc, "localTransactionStarted");
          }
          return;
      }