Part of javax.transaction.Synchronization interface,
This method is called by the Transaction Manager prior to the
start of the transaction completion process.
346825
@Override
    public void beforeCompletion() {
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) { 
            Tr.entry(this, tc, "beforeCompletion");
            Tr.exit(this, tc, "beforeCompletion");
        }
    }
713745
@Override
    protected void beforeWaitForSynchronization(final T message) throws CouldNotPerformException {
        transactionIdField = ProtoBufFieldProcessor.getFieldDescriptor(message, TransactionIdProvider.TRANSACTION_ID_FIELD_NAME);
        if (transactionIdField == null) {
            throw new NotAvailableException("transaction id field for message[" + message.getClass().getSimpleName() + "]");
        }

        if (transactionIdField.getType() != Type.UINT64) {
            throw new CouldNotPerformException("Transaction id field of message[" + message.getClass().getSimpleName() + "] has an unexpected type[" + transactionIdField.getType().name() + "]");
        }
    }
192019
private Transaction onBegin()
    {
        Transaction tx;
        if (((StatelessSessionImpl) s).getTransactionCoordinator().isTransactionActive())
        {
            tx = ((StatelessSessionImpl) s).getTransaction();
        }
        else
        {
            tx = s.beginTransaction();
        }
        return tx;
    }
1279405
private final void complete(Transaction tx, boolean readOnly)
	{
		if (log.isTraceEnabled())
			log.trace("Complete " + tx);

		if (!readOnly)
			tx.commit();
		else
			tx.rollback();
	}
871230
void prePrepare(Transaction transaction)
                    throws ObjectManagerException
    {
        throw new InvalidStateException(this, InternalTransaction.stateTerminated, InternalTransaction.stateNames[InternalTransaction.stateTerminated]);
    }
1215429
@Override
    public void afterCompletion(int status)
    {

        boolean committed = true;
        boolean reLoad = false;
        final boolean isTraceOn = TraceComponent.isAnyTracingEnabled(); // d532639.2

        if (status != Status.STATUS_COMMITTED) {
            committed = false;
        }

        if (isTraceOn && TETxLifeCycleInfo.isTraceEnabled()) // PQ74774
        { // PQ74774
            String tid = getTxId();
            if (tid != null)
            {
                if (globalTransaction)
                {
                    TETxLifeCycleInfo.traceGlobalTxAfterCompletion(tid, "Global/User Tx AfterCompletion");
                } else
                {
                    TETxLifeCycleInfo.traceLocalTxAfterCompletion(tid, "Local Tx AfterCompletion");
                }
            }
        } // PQ74774

        //d139562.11
        if (finderSyncList != null) // d173022.12
        { // d173022.12
            int numberofCallers = finderSyncList.size();
            for (int i = 0; i < numberofCallers; ++i) {
                finderSyncList.get(i).afterCompletion(status);
            }
        } // d173022.12

        if (isTraceOn && tc.isEntryEnabled()) // d144064
            Tr.entry(tc, "afterCompletion"
                     , new Object[] { Boolean.valueOf(globalTransaction), this,
                                     Boolean.valueOf(committed),
                                     Boolean.valueOf(isActivitySessionCompleting) }
                            ); //123293

        // When an EJB method ends, we need to remove bean-specific contexts from
        // the thread.  Those contexts need to be present for beforeCompletion for
        // JPA @PreUpdate, so postInvoke cannot pop the contexts prior to
        // transaction completion, but the calls to Activator.commit/.rollbackBean
        // below might unpin the currently invoked bean from the current
        // transaction, which would allow the bean to be active concurrently on
        // another thread while other transaction callbacks are running on this
        // thread.  To avoid that, pop the contexts now if this transaction is
        // being completed because an EJB method is ending.              RTC107108
        if (ivPostInvokeContext != null)
        {
            ivContainer.postInvokePopCallbackContexts(ivPostInvokeContext);
            ivPostInvokeContext = null;
        }

        try {

            if (committed) {

                // d126930.3
                // By default activitSessionCompleting is set to true.  Even if there
                // is no activitySession present.  This simply means we follow the noraml
                // ContainerTx logic for ending a transaction.

                if (isActivitySessionCompleting == true) {

                    becomeCommitted();

                    // Since we're committing, we can now allow timers queued to
                    // start to be started (not in this list if also cancelled).
                    if (timersQueuedToStart != null) {
                        for (TimerNpImpl timer : timersQueuedToStart.values()) {
                            timer.start();
                        }
                    }

                    // Any timers canceled in this global tran were added to
                    // timersCanceled in case they needed to be re-created in
                    // rollback.  Since we're not rolling back, go ahead and
                    // destroy these, then clear this map
                    if (timersCanceled != null) {
                        for (TimerNpImpl timer : timersCanceled.values()) {
                            timer.remove(true); // RTC107334
                        }
                    }

                    // d111555  Only perform if a beanO has been enlisted
                    if (ivBeanOsEnlistedInTx) {
                        //115597 changed to use afterList
                        int afterListSize = afterList.size(); // d122418-5
                        for (int i = 0; i < afterListSize; i++) // d122418-5
                        {
                            BeanO beanO = afterList.get(i); // d122418-5
                            try {
                                beanO.commit(this);
                            } catch (Throwable ex) {
                                FFDCFilter.processException(ex,
                                                            CLASS_NAME + ".afterCompletion",
                                                            "795", this);
                                if (isTraceOn && tc.isEventEnabled()) // d144064
                                    Tr.event(tc, "Exception thrown in commit()",
                                             new Object[] { beanO, ex });
                            } finally {
                                // Perform the Activation Strategy afterCompletion -
                                // commit processing. Ignore any exception that may
                                // occur, as the transaction has already committed
                                // and insure the rest of the beans in the list
                                // get processed to minimize side effects of any
                                // failure here.                                 d145697
                                try {
                                    ivContainer.activator.commitBean(this, beanO);
                                } catch (Throwable ex) {
                                    FFDCFilter.processException(ex,
                                                                CLASS_NAME +
                                                                                ".afterCompletion",
                                                                "811", this);
                                    if (isTraceOn && tc.isEventEnabled())
                                        Tr.event(tc, "Exception thrown in commitBean()",
                                                 new Object[] { beanO, ex });
                                }
                            }
                        } // end for
                    } // if ivBeanOsEnlistedInTx               // d111555

                    // d126930.3
                    // --------------------------------------------------------------
                    // Special case added for mid-activitySession checkpoint.  Entity
                    // beans enlisted in local transactions must be stored during
                    // the checkpoint.  This occured at beforeCompletion time.  Here
                    // we just do nothing, to make sure the bean's state does not
                    // not change.
                    // --------------------------------------------------------------

                } else { //checkpoint/reset processing

                    reLoad = true;

                } // end else (special case for mid-ActivitySession checkpoint)

            } else { // JTS Status is Rollback

                // d126930.3
                // By default activitSessionCompleting is set to true.  Even if there
                // is no activitySession present.  This simply means we follow the normal
                // ContainerTx logic for ending a transaction.

                if (isActivitySessionCompleting == true) {

                    becomeRolledback();

                    // re-start any timers that had been cancelled in this global tran
                    if (timersCanceled != null) {
                        for (TimerNpImpl timer : timersCanceled.values()) {
                            timer.start();
                            if (isTraceOn && tc.isDebugEnabled()) {
                                Tr.debug(tc, "rollback re-started queued-as-canceled timer: " + timer);
                            }
                        }
                    }

                    // Do not start timers queued to start.  Rather, mark them
                    // destroyed and clear the queue.
                    if (timersQueuedToStart != null) {
                        for (TimerNpImpl timer : timersQueuedToStart.values()) {
                            timer.remove(true); // RTC107334
                            if (isTraceOn && tc.isDebugEnabled()) {
                                Tr.debug(tc, "rollback destroyed queued-to-start timer: " + timer);
                            }
                        }
                    }

                    // d111555 only preform if one or more beans in tx
                    if (ivBeanOsEnlistedInTx) { // d111555
                        int afterListSize = afterList.size(); // d122418-5
                        //d115597 changed to use afterList
                        for (int i = 0; i < afterListSize; i++) // d122418-5
                        {
                            BeanO beanO = afterList.get(i); // d122418-5
                            try {
                                beanO.rollback(this);
                            } catch (Throwable ex) {
                                FFDCFilter.processException(ex,
                                                            CLASS_NAME + ".afterCompletion",
                                                            "863", this);
                                if (isTraceOn && tc.isEventEnabled()) // d144064
                                    Tr.event(tc, "Exception thrown in rollback()",
                                             new Object[] { beanO, ex });
                            } finally {
                                // Perform the Activation Strategy afterCompletion -
                                // commit processing. Ignore any exception that may
                                // occur, as the transaction has already committed
                                // and insure the rest of the beans in the list
                                // get processed to minimize side effects of any
                                // failure here.                                 d145697
                                try {
                                    ivContainer.activator.rollbackBean(this, beanO);
                                } catch (Throwable ex) {
                                    FFDCFilter.processException(ex,
                                                                CLASS_NAME +
                                                                                ".afterCompletion",
                                                                "879", this);
                                    if (isTraceOn && tc.isEventEnabled())
                                        Tr.event(tc, "Exception thrown in rollbackBean()",
                                                 new Object[] { beanO, ex });
                                }
                            }
                        } // while
                    } // if ivBeanOsEnlistedInTx              // d111555

                    // d126930.3
                    // -------------------------------------------------------------
                    // Special case added for mid-activitySession reset.  Entity
                    // beans enlisted in local transactions must be reloaded
                    // from the backing store to erase any in-memory updates that
                    // were done up to this point (ie. reset them).  For other bean
                    // types, we do nothing on mid-activitySession reset. The local
                    // transaction service will make a setCompleting = false call on
                    // the containerSynchronization interface, followed by an
                    // afterCompletion call.  These calls are not preceeded a
                    // a beforeCompletion call.  The beans' state should not be
                    // changed.  We just reload them.
                    // -------------------------------------------------------------

                } else {
                    reLoad = true;
                }

            } // end else (rollback)

        } catch (Throwable t) {

            FFDCFilter.processException(t, CLASS_NAME + ".afterCompletion",
                                        "913", this);
            if (isTraceOn && tc.isEventEnabled()) // d144064
                Tr.event(tc, "Exception during afterCompletion", t);
            throw new RuntimeException(t.toString());

        } finally { //110762.1

            // Persistence Manager wants notified

            try {
                if (txListener != null)
                    try {
                        txListener.afterCompletion(status); // d160445
                        txListener = null;
                    } catch (Throwable e) {
                        FFDCFilter.processException(e, CLASS_NAME + ".afterCompletion",
                                                    "929", this);
                        throw new Exception("txListener exception" + e.toString());
                    }
            } catch (Throwable e) {
                FFDCFilter.processException(e, CLASS_NAME + ".afterCompletion",
                                            "934", this);
            }

            if (!reLoad)
                ivContainer.containerTxCompleted(this); //d153430 added reLoad flag
        } // end finally

        // Activity session checkpoint.

        if (reLoad && afterList != null && !afterList.isEmpty()) { // d630940
            // Reset flag so beans will return to normal ContainerTx logic
            // unless another activitySession checkpoint or reset call is made.

            // Save the BeanOs processed in the following loop in an instance variable
            // so methods called from the customer callbacks can determine which beanO
            // is active on the thread. Access the BeanO in the loop in a local
            // variable for performance.                                       d168509
            EJBThreadData threadData = EJSContainer.getThreadData(); // d630940
            boolean popCallbackBeanO = false;
            ComponentMetaData prevCMD = null;
            boolean resetCMD = false;
            ClassLoader prevClassLoader = null;
            Object origClassLoader = ThreadContextAccessor.UNCHANGED;

            try
            {
                int afterListSize = afterList.size();
                for (int i = 0; i < afterListSize; i++)
                {
                    BeanO beanO = afterList.get(i);
                    try
                    {
                        BeanMetaData bmd = beanO.home.beanMetaData;

                        if (bmd.type == InternalConstants.TYPE_CONTAINER_MANAGED_ENTITY ||
                            bmd.type == InternalConstants.TYPE_BEAN_MANAGED_ENTITY)
                        {
                            attachListener();
                            if (txListener != null) {
                                txListener.afterBegin();
                            } else {
                                throw new Exception("Error: Null Transaction Listener");
                            }

                            // If the Entity bean has exclusive access to the data
                            // (OptA) or the LoadPolicy has defined a reload interval
                            // (ReadOnly), then there is no need to re-load the
                            // bean.  Otherwise, the Entity bean must be reloaded
                            // to acquire the proper DB locks. The forUpdate = false
                            // parameter has no effect because these are EJB 2.0
                            // beans.  Both BMP and CMP entities must use the
                            // access intent information from the application
                            // profile to determine the locking requirements.
                            // Also, we make sure the correct ComponentMetaData
                            // and local transaction context is on the thread before
                            // loading the bean.
                            if (bmd.optionACommitOption ||
                                bmd.ivCacheReloadType != BeanMetaData.CACHE_RELOAD_NONE)
                            {
                                // Bean is not re-loaded, but PM needs to be informed
                                // the bean is enlisted with the tran.               LI3408
                                ((EntityBeanO) beanO).enlistForOptionA(this);
                            }
                            else
                            {
                                threadData.pushCallbackBeanO(beanO); // d168509, d630940
                                popCallbackBeanO = true;

                                // Update the thread CMD if it's not the same as the
                                // previous bean and this is a bean-managed bean.
                                if (bmd != prevCMD &&
                                    bmd.type == InternalConstants.TYPE_BEAN_MANAGED_ENTITY)
                                {
                                    if (resetCMD)
                                    {
                                        cmdAccessor.endContext();
                                    }

                                    cmdAccessor.beginContext(bmd);
                                    prevCMD = bmd;
                                    resetCMD = true;

                                    // Update the class loader if it's not the same as the
                                    // previous bean.                         PK51366, PK83186
                                    ClassLoader classLoader = bmd.ivContextClassLoader; // F85059
                                    if (classLoader != prevClassLoader)
                                    {
                                        prevClassLoader = classLoader;
                                        origClassLoader = EJBThreadData.svThreadContextAccessor.repushContextClassLoaderForUnprivileged(origClassLoader, classLoader);
                                    }
                                }

                                Object cmdCtxSet = null;
                                TxContextChange changedContext = null;
                                try {
                                    cmdCtxSet = cmdAccessor.beginContext(bmd);
                                    changedContext = uowCtrl.setupLocalTxContext(beanO.getId());
                                    ((EntityBeanO) beanO).load(this, false);
                                } finally {
                                    uowCtrl.teardownLocalTxContext(changedContext);
                                    if (cmdCtxSet != null) {
                                        cmdAccessor.endContext();
                                    }
                                }

                                popCallbackBeanO = false;
                                threadData.popCallbackBeanO();
                            }
                        }

                    } catch (Throwable ex) {
                        FFDCFilter.processException(ex,
                                                    CLASS_NAME + ".afterCompletion",
                                                    "978", this);
                        if (isTraceOn && tc.isEventEnabled()) // d144064
                            Tr.event(tc, "Exception thrown attempting to reload bean " +
                                         "due to activitySession reset",
                                     new Object[] { beanO, ex });

                        //d135218 - added destroy, setRollbackOnly, logException, &
                        //          throw exception below to match beforeCompletion
                        //          logic since ActiviySession reset occurs during
                        //          the middle of a local transaction, not at the
                        //          end, like afterCompletion usually handles.

                        // Destroy the beanO, too late to delist. Destroying it should
                        // take care of the state when the transaction is rolled back
                        beanO.destroy();

                        ivContainer.uowCtrl.setRollbackOnly();

                        // Log the exception
                        ExceptionUtil.logException(tc, ex, null, beanO);

                        // Inform the activitySession service that reset
                        // failed.
                        throw new RuntimeException(ex.toString());

                    }
                } // end for loop
            } finally
            {
                EJBThreadData.svThreadContextAccessor.popContextClassLoaderForUnprivileged(origClassLoader);

                if (resetCMD)
                {
                    cmdAccessor.endContext();
                }

                if (popCallbackBeanO)
                {
                    threadData.popCallbackBeanO();
                }
            }

        } // end else (special case for mid-ActivitySession reset)

        if (isTraceOn && tc.isEntryEnabled())
            Tr.exit(tc, "afterCompletion"); // d144064

    }
283504
@Override
    public void afterCompletion(int status) {
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) { 
            Tr.entry(this, tc, "afterCompletion", status);
        }

        if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) { 
            Tr.debug(this, tc, "Using transaction wrapper@" + Integer.toHexString(this.hashCode()));
        }


        // When afterCompletionCode is called we need to reset the registeredForSync flag.
        registeredForSync = false;

        /*
         * Mark the transaction complete in the wrapper
         */

        // Do NOT catch runtime exceptions here.  Let them flow out
        // of the component.
        mcWrapper.transactionComplete();

        // Check if any connection handles are still in use
        if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) { 
            if (mcWrapper.getHandleCount() != 0) {
                // Issue warning that Connections have not been closed by
                // the end of the current UOW scope and will be closed
                // by the CM.
                //            Tr.warning(this, tc,"HANDLE_NOT_CLOSED_J2CA0055");
                // removed null check on mcWrapper since it is redundant from the above code (mcWrapper.getUOWCoordinator())
                String pmiName = mcWrapper.gConfigProps.cfName;
                Tr.debug(this, tc, "Information:  handle not closed at end of UOW for resource " + pmiName);
            }
        }

        // Do NOT catch the runtime exception which getConnectionManager
        // might throw. If this is thrown it is an internal bug and needs
        // to be fixed. Allow the rte to flow up to the container.
        boolean shareable = mcWrapper.getConnectionManager().shareable();

        //
        // If the connection is shareable, or it is non-shareable and the
        // handleCount is zero, then release it back to the poolManger,
        // otherwise simply reset the transaction related variables.
        //
        // Note: shareable connections are released at the end of
        // transactions regardless of outstanding handles because we don't
        // support handled being associated to an active
        //  managedConnection outside of a sharing boundary.
        if ((shareable) || (!shareable && mcWrapper.getHandleCount() == 0)) {
            if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) { 
                Tr.debug(this, tc, "afterCompletionCode: Releasing the connection to the pool. Shareable = " + shareable);
            }

            try {
                mcWrapper.releaseToPoolManager();
            } catch (Exception e) {
                // Do not rethrow the exception here since the client has
                // successfully completed the transaction.
                // Log the error and go on.

                // need to change the "291" number below
                com.ibm.ws.ffdc.FFDCFilter.processException(e, "com.ibm.ejs.j2c.RRSLocalTransactionWrapper.afterCompletion", "291", this);
                if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) { 
                    String pmiName = mcWrapper.gConfigProps.cfName;
                    Tr.debug(this, tc, "afterCompletionCode for resource " + pmiName + ":  caught Exception", e);
                }
            }

        } // end ((shareable) || (!shareable && mcWrapper.getHandleCount() == 0))
        else {
            /*
             * The cleanup of the coordinator and enlisted flag should
             * only be done here for non sharable connections. In other cases,
             * the coord is set to null in mcWrapper.releaseToPoolManager().
             * We only need to worry about this here if the handleCount is
             * greater than 0 (in which case the cleanup will be done
             * by the poolManager). Same thing for the tranFailed flag in
             * the MCWrapper.
             */
            enlisted = false;
            //     mcWrapper.setTranFailed(false);
            mcWrapper.setUOWCoordinator(null);
        }

        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
            Tr.exit(this, tc, "afterCompletion");

    }
706134
public void complete() {
        long seqNo = this.operation.getSequenceNumber();
        Preconditions.checkState(seqNo >= 0, "About to complete a CompletableOperation that has no sequence number.");

        this.done = true;
        if (this.successHandler != null) {
            Callbacks.invokeSafely(this.successHandler, null, cex -> log.error("Success Callback invocation failure.", cex));
        }
    }
180691
protected void prepareTransactionMemoriesIfExists() {
        final SavedTransactionMemories memories = ThreadCacheContext.findTransactionMemories();
        if (memories != null) {
            final List<TransactionMemoriesProvider> providerList = memories.getOrderedProviderList();
            final StringBuilder sb = new StringBuilder();
            for (TransactionMemoriesProvider provider : providerList) {
                provider.provide().ifPresent(result -> sb.append("\n*").append(result));
            }
            final WholeShowAttribute attribute = new WholeShowAttribute(sb.toString().trim());
            requestManager.setAttribute(LastaWebKey.DBFLUTE_TRANSACTION_MEMORIES_KEY, attribute);
        }
    }
71693
public static boolean isCompleted(Transaction tx)
   {
      if (tx == null)
         return true;
      
      try
      {
         int status = tx.getStatus();

         return status == Status.STATUS_COMMITTED ||
            status == Status.STATUS_ROLLEDBACK ||
            status == Status.STATUS_NO_TRANSACTION;
      }
      catch (SystemException error)
      {
         throw new RuntimeException("Error during isCompleted()", error);
      }
   }
467112
protected void backout(boolean reUse,
                           Transaction transaction)
                    throws ObjectManagerException {
        final String methodName = "backout";
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this, cclass, methodName, new Object[] { new Boolean(reUse),
                                                                transaction });

        boolean persistentWorkDone = false;
        ManagedObject[] lockedManagedObjects;
        int numberOfLockedManagedObjects = 0;

        synchronized (this) {
            // To defend against two application threads completing the same transaction and trying to
            // continue with it at the same time we check that the Transaction still refers to this one,
            // now that we are synchronized on the InternalTransaction.
            if (transaction.internalTransaction != this) {
                if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                    trace.exit(this, cclass,
                               methodName,
                               new Object[] { "via InvalidTransactionException", transaction.internalTransaction }
                                    );
                // Same behaviour as if the transaction was completed and replaced by
                // objectManagerState.dummyInternalTransaction.
                throw new InvalidStateException(this,
                                                InternalTransaction.stateTerminated,
                                                InternalTransaction.stateNames[InternalTransaction.stateTerminated]);

            } // if (transaction.internalTransaction != this).

            // Only call prePrepare if we have not already prepared the transaction.
            if (state == stateInactive
                || state == stateActiveNonPersistent
                || state == stateActivePersistent) {
                prePrepare(transaction);
            } // If already prepared.

            testState(nextStateForStartBackout);
            setState(nextStateForStartBackout);

            preBackout(transaction); // Tell ManagedObjects the outcome.

            // Is there any logging to do?
            if (state == stateBackingOutPersistent) {
                persistentWorkDone = true;

                TransactionBackoutLogRecord transactionBackoutLogRecord = new TransactionBackoutLogRecord(this);
                objectManagerState.logOutput.writeNext(transactionBackoutLogRecord,
                                                       -logSpaceReserved,
                                                       true,
                                                       true);
                logSpaceReserved = 0;
            } // If logging work to do.

            // Drive the backout method for the included objects.
            // The synchronized block prevents us from taking a checkpoint until all of the
            // ManagedObjects have had their opportunity to update the ObjectStore. If a
            // checkpoint is currently active we will update the current checkpoint set in
            // the ObjectStore, if not we will update the next set of updates.
            lockedManagedObjects = new ManagedObject[includedManagedObjects.size()];

            boolean requiresCurrentPersistentCheckpoint = requiresPersistentCheckpoint
                                                          || (objectManagerState.checkpointStarting == ObjectManagerState.CHECKPOINT_STARTING_PERSISTENT);

            for (java.util.Iterator managedObjectIterator = includedManagedObjects.values().iterator(); managedObjectIterator.hasNext();) {
                ManagedObject managedObject = (ManagedObject) managedObjectIterator.next();
                long managedObjectSequenceNumber = ((Long) managedObjectSequenceNumbers.get(managedObject.owningToken)).longValue();

                if (managedObject.lockedBy(transaction)) {
                    managedObject.backout(transaction,
                                          managedObjectSequenceNumber,
                                          requiresCurrentPersistentCheckpoint);
                    lockedManagedObjects[numberOfLockedManagedObjects++] = managedObject;
                } else {
                    ObjectManagerByteArrayOutputStream serializedBytes = (ObjectManagerByteArrayOutputStream) loggedSerializedBytes.get(managedObject.owningToken);
                    managedObject.optimisticReplaceBackout(transaction,
                                                           serializedBytes,
                                                           managedObjectSequenceNumber,
                                                           requiresCurrentPersistentCheckpoint);
                } // if(managedObject.lockedBy(transaction)).

            } // for... includedManagedObjects.

            setState(nextStateForBackout);
            transactionLock.unLock(objectManagerState);
            postBackout(transaction); // Tell ManagedObjects the outcome is complete.
            // Tidy up the transaction.
            complete(reUse,
                     transaction);
        } // synchronized (this).

        // We don't want to clear the transaction lock held by the managedObject otherwise
        // ManagedObject.wasLocked() will not be able to give the past locked state. The
        // Unlock point wa noted above so now notify the ManagedObject and give a new
        // waiter a chance to acquire the lock. If a new transaction acquires the lock then
        // ManagedObject.wasLocked will return its result for the new transaction and
        // wasLocked() will then be true for an even later time.  Do this after we have release the
        // synchronize lock on InternalTransaction so that we avoid deadlock with ManagedObjects
        // that invoke synchronized InternalTransaction methods.
        for (int i = 0; i < numberOfLockedManagedObjects; i++) {
            synchronized (lockedManagedObjects[i]) {
                lockedManagedObjects[i].notify();
            } // synchronized (lockedManagedObjects[i]).
        } // for... lockedManagedObjects.

        // Tell the ObjectManager that we are done, once the transaction is unlocked
        // in case it is needed for checkpoint.
        objectManagerState.transactionCompleted(this,
                                                persistentWorkDone);
        // See if we need to delay while a checkpoint completes. Applications amy ask to reUSe
        // the same transaction, if so we introduce the delay here. Internal transactions are never
        // reUsed so we don't need to wory about blocking them. This call must be made when we
        // are not synchronized on the transaction because it might block waiting for a checkpoint
        // to complete if the log is full.
        if (reUse)
            objectManagerState.transactionPacing();

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this, cclass, methodName);
    }
492412
@Override
	public void commitChanges( SynchronizationBarrier barrier ) throws JMSException
    {
    	checkNotClosed();
    	checkTransactionLock();
    	
    	if (persistentStore != null)
    	{
    		long start = System.currentTimeMillis();
    		synchronized (storeLock)
			{
    			persistentStore.commitChanges(barrier);
			}
    		long end = System.currentTimeMillis();
    		notifyCommitTime(end-start);

    		// Clear pending commit flag
    		pendingChanges = false;
    	}
    }
986963
public void startTransaction()
   {
      Long key = Long.valueOf(Thread.currentThread().getId());
      TransactionImpl tx = txs.get(key);

      if (tx == null)
      {
         TransactionImpl newTx = new TransactionImpl(key);
         tx = txs.putIfAbsent(key, newTx);
         if (tx == null)
            tx = newTx;
      }

      tx.active();
   }
813613
@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;
    }
875321
@Override
	public void begin() throws TransactionManagementException {
		logger.entering(CLASSNAME, "begin");
		
		try {
			userTran.begin();
			logger.log(Level.FINE, "javax.transaction.Status: {0}", userTran.getStatus());
		} catch (NotSupportedException e) {
			throw new TransactionManagementException(e);
		} catch (SystemException e) {
			throw new TransactionManagementException(e);
		}
		logger.exiting(CLASSNAME, "begin");
	}
706399
public final synchronized void notifyCompletion() {
        if (tc.isEntryEnabled())
            Tr.entry(tc, "notifyCompletion", "finishCount=" + _finishCount);

        if (--_finishCount < 0) {
            // may need to make final state transition here ?
            try {
                switch (_status.getState()) {
                    case TransactionState.STATE_COMMITTING:
                    case TransactionState.STATE_HEURISTIC_ON_COMMIT:
                        _status.setState(TransactionState.STATE_COMMITTED);
                        break;
                    case TransactionState.STATE_ROLLING_BACK:
                    case TransactionState.STATE_HEURISTIC_ON_ROLLBACK:
                        _status.setState(TransactionState.STATE_ROLLED_BACK);
                        break;

                    // one phase commit that resulted in retries ...
                    case TransactionState.STATE_PREPARING:
                    case TransactionState.STATE_COMMITTING_ONE_PHASE:
                        _status.setState(TransactionState.STATE_COMMITTED);
                } // end switch
            } catch (SystemException se) {
                FFDCFilter.processException(se, "com.ibm.tx.jta.TransactionImpl.notifyCompletion", "2416", this);
                if (tc.isDebugEnabled())
                    Tr.debug(tc, "SystemException setting state during completion processing", se);
                // swallow this exception ... we're called in finally blocks!
            } finally {
                forgetTransaction(true);
            }
        } // end if
        if (tc.isEntryEnabled())
            Tr.exit(tc, "notifyCompletion");

    }
667274
@Override
    public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException,
            SecurityException, IllegalStateException, SystemException
    {
        Transaction tx = threadLocal.get();

        try
        {
            if (tx != null)
            {
                if (log.isDebugEnabled())
                    log.info("Commiting transaction:" + tx);
                tx.commit();
            }
            else
            {
                log.debug("Cannot locate a transaction to commit.");

            }
        }
        finally
        {
            if (log.isDebugEnabled())
                log.info("Resetting after commit.");
            threadLocal.set(null);
            timerThead.set(null);
        }
    }