/*
Suspend any global transaction
430973
protected void suspendTransaction() {
        //create local variable - JIT performance improvement
        final boolean isTraceOn = com.ibm.websphere.ras.TraceComponent.isAnyTracingEnabled();
        if (isTraceOn && LoggingUtil.SESSION_LOGGER_WAS.isLoggable(Level.FINE)) {
            LoggingUtil.SESSION_LOGGER_WAS.entering(methodClassName, methodNames[SUSPEND_TRANSACTION]);
        }
        Object[] suspendedTx = { null, null }; // PM56632
        //        UOWCurrent uowCurrent = TransactionManagerFactory.getUOWCurrent();
        UOWCurrent uowCurrent = this.getDatabaseStoreService().getUOWCurrent();
        UOWCoordinator uowCoord = uowCurrent.getUOWCoord();
        //        LocalTransactionCurrent ltCurrent = TransactionManagerFactory.getLocalTransactionCurrent(); //d120870.2
        LocalTransactionCurrent ltCurrent = this.getDatabaseStoreService().getLocalTransactionCurrent();

        if (uowCoord == null) {
            // There is no Global or Local Transaction
            // We must start a LocalTransaction
            if (isTraceOn && LoggingUtil.SESSION_LOGGER_WAS.isLoggable(Level.FINE)) {
                LoggingUtil.SESSION_LOGGER_WAS.logp(Level.FINE, methodClassName, methodNames[SUSPEND_TRANSACTION], "No Global or Local Transaction exists");
            }
        } else if (!uowCoord.isGlobal()) {
            // There is a LocalTransaction, it must be suspended
            // and a new LocalTransaction begun
            if (isTraceOn && LoggingUtil.SESSION_LOGGER_WAS.isLoggable(Level.FINE)) {
                LoggingUtil.SESSION_LOGGER_WAS.logp(Level.FINE, methodClassName, methodNames[SUSPEND_TRANSACTION], "LocalTransaction is active so suspend");
            }
            // Suspend the LocalTransaction and return the LocalTransactionCoordinator as an Object
            suspendedTx[0] = (Object) ltCurrent.suspend();

        } else {
            // else we have a global transaction
            if (isTraceOn && LoggingUtil.SESSION_LOGGER_WAS.isLoggable(Level.FINE)) {
                LoggingUtil.SESSION_LOGGER_WAS.logp(Level.FINE, methodClassName, methodNames[SUSPEND_TRANSACTION], "Global Transaction is Active");
                LoggingUtil.SESSION_LOGGER_WAS.logp(Level.FINE, methodClassName, methodNames[SUSPEND_TRANSACTION], "Global Transaction is Active so suspend");
            }
            try {
                //                suspendedTx = TransactionManagerFactory.getTransactionManager().suspend();
                suspendedTx[0] = this.getDatabaseStoreService().getEmbeddableWebSphereTransactionManager().suspend();
            } catch (Throwable th) {
                // Only required as JTA specifies exception, but implementation never throws one
            }
            // START: PM56632 need to check if there is a local transaction since global suspend does not suspend local transaction
            uowCoord = this.getDatabaseStoreService().getUOWCurrent().getUOWCoord();
            if (uowCoord != null && !uowCoord.isGlobal()) {
                if (isTraceOn && LoggingUtil.SESSION_LOGGER_WAS.isLoggable(Level.FINE)) {
                    LoggingUtil.SESSION_LOGGER_WAS.logp(Level.FINE, methodClassName, methodNames[SUSPEND_TRANSACTION], "LocalTransaction is active after global suspend");
                }
                // Suspend the LocalTransaction and return the LocalTransactionCoordinator as an Object
                suspendedTx[1] = (Object) ltCurrent.suspend();
            }
            // END: PM56632
        }

        if (suspendedTx[0] != null || suspendedTx[1] != null)
            suspendedTransactions.put(Thread.currentThread(), suspendedTx);

        try {
            if (isTraceOn && LoggingUtil.SESSION_LOGGER_WAS.isLoggable(Level.FINE)) {
                LoggingUtil.SESSION_LOGGER_WAS.logp(Level.FINE, methodClassName, methodNames[SUSPEND_TRANSACTION], "Starting a Local Transaction");
            }
            //            ltCurrent.begin();
            boolean boundaryIsAS = false; // true if the boundary is ActivitySession; false if the boundary is BeanMethod
            boolean unresActionIsCommit = false; // true if the unresolved action is commit; false if it is rollback
            boolean resolverIsCAB = false; // true if the resolver is ContainerAtBoundary; false if it is Application
            //          The following Starts a new LTC scope and associates it with the current thread.
            //          The configuration of the LTC is determined by the caller rather than via J2EE component metadata.
            //          Throws IllegalStateException if the LocalTransactionCoordinator is not in a
            //          valid state to execute the operation, for example if a global transaction is active.
            ltCurrent.begin(boundaryIsAS, unresActionIsCommit, resolverIsCAB);
        } catch (Exception ex) {
            // Absorb any exception to ensure we still exit cleanly and resume
            // any suspended LTC in postInvoke.
            LoggingUtil.SESSION_LOGGER_WAS.logp(Level.SEVERE, methodClassName, methodNames[SUSPEND_TRANSACTION], "DatabaseHashMap.cantstartLTC");
        }

        if (isTraceOn && LoggingUtil.SESSION_LOGGER_WAS.isLoggable(Level.FINER)) {
            LoggingUtil.SESSION_LOGGER_WAS.exiting(methodClassName, methodNames[SUSPEND_TRANSACTION]);
        }
    }
381740
@Override
    public void suspend()
    {
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
            Tr.entry(tc, "suspend");

        _suspendedUOWType = ((UOWCurrent) _tranManager).getUOWType();

        switch (_suspendedUOWType)
        {
            case UOWCurrent.UOW_LOCAL:

                if (TraceComponent.isAnyTracingEnabled() && tc.isEventEnabled()) {
                    Tr.event(tc, "suspending (local)");
                }

                _suspendedUOW = LocalTranCurrentSet.instance().suspend();

                break;

            case UOWCurrent.UOW_GLOBAL:

                if (TraceComponent.isAnyTracingEnabled() && tc.isEventEnabled()) {
                    Tr.event(tc, "suspending (global)");
                }

                _suspendedUOW = _tranManager.suspend();

                break;

            case UOWCurrent.UOW_NONE:

                _suspendedUOW = null;
                break;

            default:
                break;
        }

        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
            Tr.exit(tc, "suspend", _suspendedUOWType);
    }
255364
public final void onPrepareCommand(GlobalTransaction globalTransaction, boolean local) {
      //NB: If I want to give up using the InboundInvocationHandler, I can create the remote transaction
      //here, just overriding the handlePrepareCommand
      TransactionStatistics txs = getTransactionStatistic(globalTransaction, local);
      if (txs == null) {
         log.prepareOnUnexistingTransaction(globalTransaction == null ? "null" : globalTransaction.globalId());
         log.error("Trying to invoke onPrepareCommand() but no transaction is associated");
         return;
      }
      txs.onPrepareCommand();
   }
1081955
public final void beginTransaction(GlobalTransaction globalTransaction, boolean local) {
      if (local) {
         //Not overriding the InitialValue method leads me to have "null" at the first invocation of get()
         TransactionStatistics lts = createTransactionStatisticIfAbsent(globalTransaction, true);
         if (trace) {
            log.tracef("Local transaction statistic is already initialized: %s", lts);
         }
      } else {
         TransactionStatistics rts = createTransactionStatisticIfAbsent(globalTransaction, false);
         if (trace) {
            log.tracef("Using the remote transaction statistic %s for transaction %s", rts, globalTransaction);
         }
      }
   }
235494
private void registerGlobalTxTable(GlobalComponentRegistry globalComponentRegistry) {
      InternalCacheRegistry registry = globalComponentRegistry.getComponent(InternalCacheRegistry.class);
      ConfigurationBuilder builder = new ConfigurationBuilder();
      //we can't lose transactions. distributed cache can lose data is num_owner nodes crash at the same time
      builder.clustering().cacheMode(globalComponentRegistry.getGlobalConfiguration().isClustered() ?
            CacheMode.REPL_SYNC :
            CacheMode.LOCAL);
      builder.transaction().transactionMode(TransactionMode.NON_TRANSACTIONAL);
      //persistent? should we keep the transaction after restart?
      registry.registerInternalCache(GLOBAL_TX_TABLE_CACHE_NAME, builder.build(),
            EnumSet.noneOf(InternalCacheRegistry.Flag.class));
   }
1051932
@Override
    public void unimportTransaction(String globalId) throws SystemException {

        DistributableTransaction tx = _threadImportedTran.get();

        // In the case of the in-process http channel, where no WS-AT
        // context is being propagated, we get the situation where there is a global tran
        // on the thread at this point but it is not imported
        if (tx != null) {
            if (!globalId.equals(tx.getGlobalId())) {
                // ???
                final SystemException e = new SystemException();
                throw e;
            }

            final Transaction suspendedTx = _tm.suspend();
            // If zOS and isSupportWSAT=false then there is no tx to suspend
            if ((suspendedTx != null) && (!tx.equals(suspendedTx))) {
                // Something is badly wrong
                final SystemException e = new SystemException();
                throw e;
            }
        }

        _threadImportedTran.set(null);

        // d238113 - check for null although with defect 235471.2 we should not get this problem
        if (tx != null) {
            tx.removeAssociation();
        }

        final UOWCoordinator suspendedUOW = _threadUOWCoord.get();
        // ? Should null be forced back ? - shouldn't happen anyway, LTC must have been on the thread
        if (suspendedUOW != null && !suspendedUOW.isGlobal()) {
            LocalTranCurrentSet.instance().resume((LocalTransactionCoordinator) suspendedUOW);
        }

        _threadUOWCoord.set(null);
    }
494541
public void stopTransaction(TransactionWrapper transaction) throws DataAccessException {
        if (logger.isTraceEnabled()) {
            logger.trace("stopTransaction");
        }
        if (transaction==null) {
            if (logger.isTraceEnabled())
                logger.trace("   ... transaction is null");
            return;
        }
        if (!transaction.isTransactionAlreadyStarted()) {
            DataAccessException exception = null;
            if (!transaction.isDatabaseConnectionAlreadyOpened()) {
                if (!(db.getConnection() instanceof XAConnection)) {
                    if (transaction.isRollbackOnly()) db.rollback();
                    else {
                        try {
                            db.commit();
                        } catch (SQLException e) {
                            exception = new DataAccessException(0, "Fail to commit", e);
                        }
                    }
                }
                db.closeConnection();
            } else {
                if (logger.isTraceEnabled())
                    logger.trace("   ... database opened by others");
            }
            try {
                TransactionUtil transUtil = TransactionUtil.getInstance();
                TransactionManager transManager = transUtil.getTransactionManager();
                if (transaction.isRollbackOnly()) transManager.rollback();
                else transManager.commit();
                transUtil.setCurrentConnection(null);
                //transUtil.clearCurrentConnection();
            } catch (Exception e) {
                throw new DataAccessException(0, "Fail to stop the transaction", e);
            }
            if (exception!=null) throw exception;
        } else {
            if (logger.isTraceEnabled())
                logger.trace("   ... transaction started by others");
        }
    }
1141606
public final void markAsWriteTransaction(GlobalTransaction globalTransaction, boolean local) {
      TransactionStatistics txs = getTransactionStatistic(globalTransaction, local);
      if (txs == null) {
         log.markUnexistingTransactionAsWriteTransaction(globalTransaction == null ? "null" : globalTransaction.globalId());
         return;
      }
      txs.markAsUpdateTransaction();
   }
663558
@Override
    public boolean importTransaction(String globalId, int expires) throws SystemException {

        //The first thing we need to do is distinguish between local and remote invocations. If the UOW currently associated
        //with the thread is a global txn then we know the invocation must be local. The other case is where the remote servers
        //web container has begun a local txn in the absence of the global context. We do know that there was a global txn on 
        //invocation else there wouldn't even be a cc available.
        final UOWCoordinator uowCoord = _uowc.getUOWCoord();
        _threadUOWCoord.set(uowCoord);

        if (uowCoord != null && uowCoord.isGlobal()) {
            if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                Tr.debug(tc, "The Web Service request is a local invocation");

            ((DistributableTransaction) uowCoord).resumeAssociation();
            return false;
        }

        if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
            Tr.debug(tc, "The Web Service request is a remote invocation");

        try {
            TMHelper.checkTMState();
        } catch (NotSupportedException e) {
            final SystemException se = new SystemException();
            se.initCause(e);
            throw se;
        }

        //The web container will start a local tran as there will not be a global context
        //on thread. We need to suspend this before attaching the global tran
        final LocalTransactionCoordinator ltc = LocalTranCurrentSet.instance().suspend();
        if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
            Tr.debug(tc, "Suspended LTC", ltc);

        boolean createdNewTransaction = false;

        DistributableTransaction tx = getTransactionForID(globalId);

        if (tx == null) {
            tx = new EmbeddableTransactionImpl(expires, globalId);
            createdNewTransaction = true;

            new TransactionWrapper((EmbeddableTransactionImpl) tx);
        }

        _threadImportedTran.set(tx);

        // Add association to police single thread per tran
        tx.addAssociation();

        // Resume transaction on this thread
        try {
            _tm.resume((Transaction) tx);
        } catch (Exception e) {
            SystemException se = new SystemException();
            se.initCause(e);
            throw se;
        }

        return createdNewTransaction;
    }
883369
public static <R> R suspendWhenNull(long intervalAsMillis,
            Supplier<R> objectSupplier) {
        R object = objectSupplier.get();
        if (object == null) {
            log.warn("Start Suspending !!!");
            long startTimeMillis = System.currentTimeMillis();
            while ((object = objectSupplier.get()) == null)
                sleep(intervalAsMillis);
            log.warn("Stop Suspending Over {} ms",
                    System.currentTimeMillis() - startTimeMillis);
        }
        return object;
    }
80863
@Override
    public void setRollbackOnly(String globalId) throws SystemException {

        final DistributableTransaction tx = getTransactionForID(globalId);

        if (tx != null) {
            tx.setRollbackOnly();
        }
    }
300357
public UOWHandle suspend() throws CSIException {
        final boolean isTraceOn = TraceComponent.isAnyTracingEnabled();
        if (isTraceOn && tc.isEntryEnabled())
            Tr.entry(tc, "suspend");
        UOWHandle toReturn = null;

        //First, look for a global Tx, if non-existant then look for a local Tx.
        //If neither are present, return a null UOWHandle

        //If a global tx coordinator is on the thread, getGlobalCoord() will return it in
        //which case we know there is a global tx on the thread. If not, getGlobalCoord
        //will return null in which case we can then try to see if there is a local tx.
        if (getGlobalCoord() != null) {
            Transaction gtx = suspendGlobalTx(TIMEOUT_CLOCK_STOP);
            toReturn = new UOWHandleImpl(gtx);
        }
        //If a local tx coordinator is on the thread, getLocalCoord will return it.  If not,
        //null will be returned.
        else if (getLocalCoord() != null) {
            LocalTransactionCoordinator ltc = suspendLocalTx();
            toReturn = new UOWHandleImpl(ltc);
        }

        if (isTraceOn && tc.isEntryEnabled())
            Tr.exit(tc, "suspend : " + toReturn);
        return toReturn;
    }
691412
protected void suspend()
    {
        if (tc.isEntryEnabled()) Tr.entry(tc, "suspend");

        _current = null;
        _state = Suspended;

        if (tc.isEntryEnabled()) Tr.exit(tc, "suspend");
    }
1040119
@Override
    public boolean replayCompletion(String globalId) {
        final DistributableTransaction tx = getTransactionForID(globalId);

        if (tx != null) {
            tx.replayCompletion();
            return true;
        }

        return false;

    }
806004
public LocalTransactionCoordinator suspend()
    {
        if (tc.isEntryEnabled()) Tr.entry(tc, "suspend", this);

        final LocalTranCoordImpl ltc = _coord;
        if (ltc != null)
        {
            _coord = null;
            ltc.suspend();           // suspend any native context
            
            invokeEventListener(ltc, UOWEventListener.SUSPEND, null);
        }

        if (tc.isEntryEnabled()) Tr.exit(tc, "suspend", ltc);
        return ltc;
    }
1256378
public void teardownLocalTxContext(TxContextChange changedContext)
    {

        LocalTransactionCoordinator activatedLocalTx = changedContext.getActivatedLocalTx();

        // If setupLocalTxContext did nothing, teardownLocalContext will do nothing

        if (activatedLocalTx != null) {

            // setupLocalTxContext must have swapped a different local tx context
            // onto thread so suspend it now (ie. make local tx sticky)

            suspendLocalTx();
            stickyLocalTxTable.put(changedContext.getKey(), activatedLocalTx);

            // If setupLocalTxContext suspended a local tx which was already on the thread,
            // resume that context now (ie. swap back the original context)

            LocalTransactionCoordinator previousLocalTx = changedContext.getSuspendedLocalTx();
            if (previousLocalTx != null) {

                resumeLocalTx(previousLocalTx);
            }

            // If setupLocalTxContext suspended a global tx which was already on the thread,
            // resume that context now (ie. swap back the original context)
            Transaction previousGlobalTx = changedContext.getSuspendedGlobalTx(); //LIDB1673.2.1.5
            if (previousGlobalTx != null) {

                try {
                    resumeGlobalTx(previousGlobalTx, TIMEOUT_CLOCK_START);
                } catch (Exception ex) {
                    FFDCFilter.processException(ex, CLASS_NAME + ".teardownLocalTxContext",
                                                "650", this);
                    if (TraceComponent.isAnyTracingEnabled() && tc.isEventEnabled()) {
                        Tr.event(tc, "Global tx resume failed", ex);
                    }
                }
            }

        } // End if setupLocalTxContext did swap contexts

    }
382281
function suspendListener(obj, eventName, target, method, callback) {
  if (!method && 'function' === typeof target) {
    method = target;
    target = null;
  }

  var actionSet = actionSetFor(obj, eventName, target, true),
      methodGuid = guidFor(method),
      action = actionSet && actionSet[methodGuid];

  actionSet[methodGuid] = null;
  try {
    return callback.call(target);
  } finally {
    actionSet[methodGuid] = action;
  }
}