docs: public void postInvoke(EJBKey key, UOWCookie uowCookie,
                             ExceptionType exType, EJBMethodInfoImpl methodInfo)
                      throws CSIException
      {
          final boolean isTraceOn = TraceComponent.isAnyTracingEnabled();
          if (isTraceOn && tc.isEntryEnabled()) { // d173022.3
              Tr.entry(tc, "postInvoke");
          }
  
          final TxCookieImpl txCookieImpl = (TxCookieImpl) uowCookie;
  
          // LIDB1181.23.5
          //--------------------------------------------------------
          // If the tx cookie is null then preinvoke went seriously
          // wrong. We cannot properly recover from this serious
          // internal error.  Mark any global transaction for
          // rollback.  If there is a local transaction we can end
          // it since it is local to this component instance.
          //--------------------------------------------------------
  
          if (txCookieImpl == null)
          {
              // Check for local transaction on this thread; if found, end it
              LocalTransactionCoordinator lCoord = getLocalCoord();
              if (lCoord != null) {
                  try
                  {
                      int resolver = methodInfo.getBeanMetaData()._localTran.getResolver();
  
                      // Is this an EJB 2.0 or newer component && the container is
                      // responsible for begin / end of connection specific local
                      // transactions (ie. RMLTs)?  For EJB 1.1 beans, local tx
                      // resolver will never be ContainerAtBoundary.  This is
                      // enforced by a check in  BeanMetaData.                  d135218
  
                      if (resolver == LocalTransactionSettings.RESOLVER_CONTAINER_AT_BOUNDARY)
                      {
                          // Complete the LTC context so enlisted resources will be
                          // rolled back. Container is responsible to automatically
                          // begin / end connections (i.e. local trancation
                          // resolver = containerAtBoundary).
  
                          lCoord.complete(LocalTransactionCoordinator.EndModeRollBack);
  
                      } else {
  
                          // Cleanup the LTC context so resources enlisted for cleanup
                          // will catch any application errors.
                          //  When resolver = application, the application code is
                          // responsible to do begin / end of the connections.
  
                          lCoord.setRollbackOnly();
                          lCoord.cleanup();
                      }
  
                  } catch (RolledbackException ex) {
  
                      // do nothing... this is normal on setRollback, followed by cleanup
  
                      FFDCFilter.processException(ex, CLASS_NAME + ".postInvoke",
                                                  "325", this);
  
                  } catch (Throwable ex) {
                      FFDCFilter.processException(ex, CLASS_NAME + ".postInvoke",
                                                  "330", this);
                      if (isTraceOn && tc.isEventEnabled()) {
                          Tr.event(tc, "Failed to complete local transaction", ex);
                      }
                  }
                  throw new CSIException("Aborted improperly started local transaction");
              }
  
              // If there was no local tx on this thread, there should be a global tx;
              // mark it for rollback
              else {
                  try {
                      setRollbackOnly();
                  } catch (Throwable ex) {
                      FFDCFilter.processException(ex, CLASS_NAME + ".postInvoke",
                                                  "345", this);
                      if (isTraceOn && tc.isEventEnabled()) {
                          Tr.event(tc, "Failed to mark global transaction for rollback", ex);
                      }
                      // By default - include cause.                            d672063
                      if (ExcludeNestedExceptions) {
                          ex = null;
                      }
                      throw new CSITransactionRolledbackException("Rolled back improperly started global transaction", ex);
  
                  }
                  throw new CSITransactionRolledbackException("Rolled back improperly started global transaction");
              }
          }
  
          final TranStrategy ts = txCookieImpl.txStrategy;
  
          try {
              if (exType == ExceptionType.NO_EXCEPTION) {
                  ts.postInvoke(key, txCookieImpl, methodInfo);
              } else {
                  ts.handleException(key, txCookieImpl, exType, methodInfo);
              }
          } finally
          {
              // LIDB1181.23.5
              //---------------------------------------
              // Resume any suspended local transaction
              //---------------------------------------
  
              LocalTransactionCoordinator suspendedLocalTx = txCookieImpl.suspendedLocalTx;
              if (suspendedLocalTx != null) {
                  try {
                      resumeLocalTx(suspendedLocalTx);
                  } catch (Exception ex) {
                      FFDCFilter.processException(ex, CLASS_NAME + ".postInvoke",
                                                  "394", this);
                      if (isTraceOn && tc.isEventEnabled()) {
                          Tr.event(tc, "Local tx resume failed", ex);
                      }
                      throw new CSIException("Local tx resume failed", ex);
                  }
  
              }
  
              // LIDB1181.23.5
              //---------------------------------------------------------------------
              // Resume any suspended global transaction
              //
              // There should be no global tx to resume if a local was resumed
              // above, but to insure the EJB Container always puts things back
              // the way it found them in preInvoke... at least look and resume
              // a global if it was also suspended. This may occur if an
              // application has used internals to begin/resume a global when
              // a local was already active on the thread.                    PI10351
              //---------------------------------------------------------------------
              Transaction suspendedTx = txCookieImpl.suspendedTx; //LIDB1673.2.1.5
  
              if (suspendedTx != null) {
                  try {
                      resumeGlobalTx(suspendedTx, TIMEOUT_CLOCK_START);
                  } catch (Exception ex) {
                      FFDCFilter.processException(ex, CLASS_NAME + ".postInvoke",
                                                  "414", this);
                      if (isTraceOn && tc.isEventEnabled()) {
                          Tr.event(tc, "Global tx resume failed", ex);
                      }
                      throw new CSIException("Global tx resume failed", ex);
                  }
                  //d174358.1
              }
          } // finally
  
          if (isTraceOn && tc.isEntryEnabled()) { // d173022.3
              Tr.exit(tc, "postInvoke");
          }
  
      }