docs: public void destroy() throws ResourceException {
          final boolean isTraceOn = TraceComponent.isAnyTracingEnabled();
  
          if (isTraceOn && tc.isEntryEnabled()) 
              Tr.entry(this, tc, "destroy");
  
          // Save the first exception to occur and raise it after all other destroy processing is complete.
          // Don't map exceptions and fire ConnectionError event from destroy because the
          // ManagedConnection is already being destroyed and there is no further action to take.
  
          ResourceException dsae = null;
  
          if (inRequest || isAborted())
              try {
                  inRequest = false;
                  mcf.jdbcRuntime.endRequest(sqlConn);
              } catch (SQLException x) {
                  if (!isAborted()) {
                      FFDCFilter.processException(x, getClass().getName(), "2447", this);
                      dsae = new DataStoreAdapterException("DSA_ERROR", x, getClass());
                  }
                  Tr.debug(tc, "Error during end request in destroy.", x);
              }
  
          if(isAborted()){
              if(isTraceOn && tc.isEntryEnabled())
                  Tr.exit(this, tc, "destroy", "ManagedConnection is aborted -- skipping destroy");
              return;
          }
  
          try {
              //  - We can't use the normal cleanup here because it dissociates
              // handles and we don't want that.  Instead we do it in pieces...
  
              cleanupTransactions(false); 
              // ManagedConnection is being destroyed. Do not reset for pooling. 
          } catch (ResourceException re) {
              FFDCFilter.processException(re,
                                          "com.ibm.ws.rsadapter.spi.WSRdbManagedConnectionImpl.destroy", "957", this);
  
              Tr.warning(tc, "DSTRY_ERROR_EX", re); 
              if (dsae == null)
                  dsae = re; 
          }
  
          //  Always clean out the jdbc connection list since they can't be reused beyond
          //  the sharing boundary
          // Synchronization is not needed here since the ConnectionManager should not be
          // calling destroy concurrently with other operations on the same ManagedConnection.
  
          ResourceException closeX = closeHandles();
          dsae = dsae == null ? closeX : dsae;
  
          // Remove the event listeners prior to closing the underlying connection and
          // destroying the statement cache. In addition to eliminating unnecessary events
          // from the JDBC driver, this also make it possible for us to determine--if we
          // ever do see a connection-closed event--that it's an unexpected close from the
          // JDBC driver rather than one we requested.
          if (poolConn != null && !mcf.isUCP)
          {
              poolConn.removeConnectionEventListener(this);
  
              if (mcf.jdbcDriverSpecVersion >= 40)
                  try {
                      poolConn.removeStatementEventListener(this);
                  } catch (UnsupportedOperationException supportX) {
                      // No FFDC code needed. The JDBC 4.0 driver ought to implement the
                      // removeStatementEventListener method, but doesn't.  A warning is not logged because
                      // there is nothing that a customer can do in response.  It is an issue in
                      // the JDBC driver.
                      if (isTraceOn && tc.isDebugEnabled())
                          Tr.debug(this, tc,
                                   "JDBC driver does not support removeStatementEventListener");
                  } catch (AbstractMethodError methErr) {
                      // No FFDC code needed. The JDBC 4.0 driver ought to implement the
                      // removeStatementEventListener method, but doesn't.  A warning is not logged because
                      // there is nothing that a customer can do in response.  It is an issue in
                      // the JDBC driver.
                      if (isTraceOn && tc.isDebugEnabled())
                          Tr.debug(this, tc,
                                   "JDBC driver does not implement removeStatementEventListener");
                  }
          }
  
          //destroy the cache
          // make sure to check if the cache is null before destroying it....
          // could be null if there was no statement cache created due to a zero for
          // statement cache size....
  
          if (statementCache != null)
              clearStatementCache(); 
  
          // Close the SQLJ default context. 
  
          if (sqljContext != null)
              try {
                  sqljContext.getClass().getMethod("close").invoke(sqljContext);
              } catch (Throwable x) {
                  FFDCFilter.processException(x, getClass().getName() + ".destroy", "2596", this);
                  if (dsae == null)
                      dsae = new DataStoreAdapterException("DSA_ERROR", x instanceof InvocationTargetException ? x.getCause() : x, getClass());
              }
          if (cachedConnection != null)
              try {
                  cachedConnection.close();
              } catch (SQLException sqlex) {
                  FFDCFilter.processException(sqlex, "com.ibm.ws.rsadapter.spi.WSRdbManagedConnectionImpl.destroy", "2607", this);
                  DataStoreAdapterException dsex = new DataStoreAdapterException("DSA_ERROR", sqlex, getClass());
                  if (dsae == null)
                      dsae = dsex;
              }
  
          // - need to cleanup the context before closing the connection.. closing connection moves to this
          if (sqlConn != null)
              try {
                  sqlConn.close();
              } catch (SQLException se) {
                  FFDCFilter.processException(se,
                                              "com.ibm.ws.rsadapter.spi.WSRdbManagedConnectionImpl.destroy", "1005", this);
                  // Creating a new exception logs a warning for the error.
                  ResourceException resX = new DataStoreAdapterException("DSA_ERROR", se, getClass());
                  if (dsae == null)
                      dsae = resX;
              }
  
          if (poolConn != null) { 
              try {
                  poolConn.close();
              } catch (SQLException se) {
                  FFDCFilter.processException(se,
                                              "com.ibm.ws.rsadapter.spi.WSRdbManagedConnectionImpl.destroy", "1024", this);
  
                  // Creating a new exception logs a warning for the error.
                  ResourceException resX = new DataStoreAdapterException("DSA_ERROR", se, getClass());
                  if (dsae == null)
                      dsae = resX;
              }
          } 
  
          //Null out all vars
  
          defaultCatalog = null; 
          defaultTypeMap = null; 
          defaultSchema = null;
          initialShardingKey = null;
          initialSuperShardingKey = null;
  
          handlesInUse = null;
  
          ivEventListeners = null;
          numListeners = 0; 
          localTran = null;
          xares = null;
          cri = null;
          subject = null;
          sqlConn = null;
          poolConn = null;
          statementCache = null; 
          sqljContext = null; 
          cachedConnection = null; 
  
          //Lastly, if there was a DataStoreAdapterException to throw from above, throw it here
          if (dsae != null) {
              if (isTraceOn && tc.isEntryEnabled()) 
                  Tr.exit(this, tc, "destroy", dsae);
              throw dsae;
          }
  
          if (isTraceOn && tc.isEntryEnabled()) 
              Tr.exit(this, tc, "destroy");
  
      }