Upon successful transaction commit status, store the value of the committed metrics.
Upon any other status value roll back the metrics to the last committed value.

@see javax.transaction.Synchronization#afterCompletion(int)
505862
@Override
    public void afterCompletion(int status) {

    	
	    logger.log(Level.FINE, "The status of the transaction commit is: " + status);
		
        if (status == Status.STATUS_COMMITTED){
        	//Save the metrics object after a successful commit
        	runtimeStepExecution.setCommittedMetrics();
        } else{
        	//status = 4 = STATUS_ROLLEDBACK;
        	runtimeStepExecution.rollBackMetrics();
        }
    }
195472
private void complete(Object value) {
        future.complete(value);
        if (context.invocationRegistry.deregister(this) && taskDoneCallback != null) {
            context.asyncExecutor.execute(taskDoneCallback);
        }
    }
405351
private void flushComplete(long lastIndexedOffset) {
        this.aggregator.reset();
        this.aggregator.setLastIndexedOffset(lastIndexedOffset);
        this.connector.notifyIndexOffsetChanged(this.aggregator.getLastIndexedOffset());
        log.debug("{}: FlushComplete (State={}).", this.traceObjectId, this.aggregator);
    }
963270
public void reset(int initialValue) throws FetchException, PersistException {
        synchronized (mStoredSequence) {
            Transaction txn = mRepository.enterTopTransaction(null);
            txn.setForUpdate(true);
            try {
                boolean doUpdate = mStoredSequence.tryLoad();
                mStoredSequence.setInitialValue(initialValue);
                // Start as small as possible to allow signed long comparisons to work.
                mStoredSequence.setNextValue(Long.MIN_VALUE);
                if (doUpdate) {
                    mStoredSequence.update();
                } else {
                    mStoredSequence.insert();
                }
                txn.commit();
                mHasReservedValues = false;
            } finally {
                txn.exit();
            }
        }
    }
297482
@Override
    public void afterCompletion(TransactionCommon tran, boolean committed)
    {
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
            SibTr.entry(tc, "afterCompletion", new Object[] { tran, Boolean.valueOf(committed) });

        // We don't care if the transaction committed or rolled back, either way
        // this callback indicates that a message that this consumer had active
        // is no longer active and therefore we should decrement the active message
        // count (this callback is called once per active message).
        removeActiveMessages(1);

        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
            SibTr.exit(tc, "afterCompletion");
    }
316958
protected void doCleanupAfterCompletion(Object transaction) {
        ContextSourceAndDataSourceTransactionObject actualTransactionObject = (ContextSourceAndDataSourceTransactionObject) transaction;

        super.doCleanupAfterCompletion(actualTransactionObject
                .getDataSourceTransactionObject());
        ldapManagerDelegate.doCleanupAfterCompletion(actualTransactionObject
                .getLdapTransactionObject());
    }
845698
@Override
    public final synchronized void beforeCompletion()
                    throws RemoteException
    {
        final boolean isTraceOn = TraceComponent.isAnyTracingEnabled();
        if (isTraceOn && tc.isEntryEnabled())
            Tr.entry(tc, "beforeCompletion: " + getStateName(state), currentTx); //123293

        if (removed) {
            if (isTraceOn && tc.isEntryEnabled())
                Tr.exit(tc, "beforeCompletion: removed");
            return;
        }

        switch (state)
        {
            case TX_METHOD_READY:
                setState(COMMITTING_OUTSIDE_METHOD);
                break;

            case TX_IN_METHOD:
                setState(COMMITTING_IN_METHOD);
                break;

            // Could happen during async rollback
            case IN_METHOD:
            case METHOD_READY:
            case DESTROYED:
                if (isTraceOn && tc.isEntryEnabled())
                    Tr.exit(tc, "beforeCompletion: asynch rollback: " + getStateName(state));
                return;

            default:
                if (isTraceOn && tc.isDebugEnabled()) // d144064
                    Tr.debug(tc, "invalid state: " + state); //123293
                throw new InvalidBeanOStateException(StateStrs[state],
                                "TX_IN_METHOD | " +
                                                "TX_METHOD_READY");

        }

        if (isTraceOn && tc.isEntryEnabled())
            Tr.exit(tc, "beforeCompletion: " + getStateName(state));

    }
277686
protected function AfterGather()
    {
        if ($this->fileCacher->MustStoreToCache())
        {
            $this->fileCacher->StoreToCache($this->output);
        }
        parent::AfterGather();
    }
536834
public void afterCommit(PBStateEvent event)
    {
        if(log.isDebugEnabled()) log.debug("afterCommit() call, push objects to application cache");
        if(invokeCounter != 0)
        {
            log.error("** Please check method calls of ObjectCacheTwoLevelImpl#enableMaterialization and" +
                    " ObjectCacheTwoLevelImpl#disableMaterialization, number of calls have to be equals **");
        }
        try
        {
            // we only push "really modified objects" to the application cache
            pushToApplicationCache(TYPE_WRITE, TYPE_CACHED_READ);
        }
        finally
        {
            resetSessionCache();
        }
    }
151770
public void afterCompletion(TransactionCommon transaction, boolean committed)
    {
        // When the reference count is about to reach zero, this class registers *itself* as
        // a transaction callback. This method then gets called after the transaction
        // completes and the item's itemReferencesDroppedToZero callback is called.
        if (isAvailable())
        {
        	try
        	{
        		Item item = (Item) getItem();
        		if (null != item)
        		{
        			item.itemReferencesDroppedToZero();
        		}
			} 
        	catch (SevereMessageStoreException e) 
        	{
	            FFDCFilter.processException(e, "com.ibm.ws.sib.msgstore.cache.links.ItemLink.afterCompletion", "1:286:1.104.1.1");
	            if (TraceComponent.isAnyTracingEnabled() && tc.isEventEnabled()) SibTr.event(this, tc, "Exception caught attempting to drop item reference count to zero!", e);
			}

        }
    }
1216435
protected void transactionComplete() {

        if (state != STATE_TRAN_WRAPPER_INUSE) {
            IllegalStateException e = new IllegalStateException("transactionComplete: illegal state exception. State = " + getStateString() + " MCW = "
                                                                + mcWrapperObject_hexString);
            Object[] parms = new Object[] { "transactionComplete", e };
            Tr.error(tc, "ILLEGAL_STATE_EXCEPTION_J2CA0079", parms);
            throw e;
        }

        state = STATE_ACTIVE_INUSE;
    }
362286
public boolean commit() {
        try {
            setWrongValueMessage(null);
            propInfo.setPropertyValue(target, getValue());
            updateValue();
            return true;
        } catch (Exception e) {
            setWrongValueException(e);
            return false;
        }
    }
4686
private void finishValue()
    {
        final ContainerInfo current = currentContainer();
        if (current != null && current.type == ContainerType.ANNOTATION)
        {
            // close out and patch the length
            popContainer();
        }
        hasWrittenValuesSinceFinished = true;
        hasWrittenValuesSinceConstructed = true;
    }
856384
synchronized boolean complete(Session session, OrderedHashSet set) {

        RowActionBase action;
        boolean readCommitted = session.isolationMode
                                == SessionInterface.TX_READ_COMMITTED;
        boolean result = true;

        action = this;

        do {
            if (action.rolledback || action.type == ACTION_NONE) {
                action = action.next;

                continue;
            }

            if (action.session == session) {
                if (action.actionTimestamp == 0) {
                    action.actionTimestamp = session.actionTimestamp;
                }
            } else {
                if (action.prepared) {
                    return false;
                }

                if (readCommitted) {
                    if (action.commitTimestamp > session.actionTimestamp) {
                        result = false;
                    } else if (action.commitTimestamp == 0
                               && action.actionTimestamp != 0) {
                        set.add(action.session);

                        result = false;
                    }
                } else if (action.commitTimestamp
                           > session.transactionTimestamp) {
                    return false;
                }
            }

            action = action.next;
        } while (action != null);

        return result;
    }
1024135
public JMProgressiveManager<T, R> getAfterCompletion() {
		try {
			completableFuture.get();
		} catch (InterruptedException | ExecutionException e) {
			handleException(log, e, "stopSync");
		}
		return this;
	}
256056
@InterfaceAudience.Private
    public void saveLastSequence() {
        if (!lastSequenceChanged) {
            return;
        }

        if (savingCheckpoint) {
            // If a save is already in progress, don't do anything. (The completion block will trigger
            // another save after the first one finishes.)
            overdueForCheckpointSave = true;
            return;
        }

        lastSequenceChanged = false;
        overdueForCheckpointSave = false;

        Log.d(Log.TAG_SYNC, "%s: saveLastSequence() called. lastSequence: %s remoteCheckpoint: %s",
                this, lastSequence, remoteCheckpoint);
        final Map<String, Object> body = new HashMap<String, Object>();
        if (remoteCheckpoint != null) {
            body.putAll(remoteCheckpoint);
        }
        body.put("lastSequence", lastSequence);

        savingCheckpoint = true;
        final String remoteCheckpointDocID = remoteCheckpointDocID();
        if (remoteCheckpointDocID == null) {
            Log.w(Log.TAG_SYNC, "%s: remoteCheckpointDocID is null, aborting saveLastSequence()", this);
            return;
        }

        final String checkpointID = remoteCheckpointDocID;
        Log.d(Log.TAG_SYNC, "%s: start put remote _local document.  checkpointID: %s body: %s",
                this, checkpointID, body);
        Future future = sendAsyncRequest("PUT", "_local/" + checkpointID, false, body, new RemoteRequestCompletion() {

            @Override
            public void onCompletion(RemoteRequest remoteRequest, Response httpResponse, Object result, Throwable e) {

                Log.d(Log.TAG_SYNC,
                        "%s: put remote _local document request finished.  checkpointID: %s body: %s",
                        this, checkpointID, body);

                try {

                    if (e != null) {
                        // Failed to save checkpoint:
                        switch (Utils.getStatusFromError(e)) {
                            case Status.NOT_FOUND:
                                Log.i(Log.TAG_SYNC, "%s: could not save remote checkpoint: 404 NOT FOUND", this);
                                remoteCheckpoint = null;  // doc deleted or db reset
                                overdueForCheckpointSave = true; // try saving again
                                break;
                            case Status.CONFLICT:
                                Log.i(Log.TAG_SYNC, "%s: could not save remote checkpoint: 409 CONFLICT", this);
                                refreshRemoteCheckpointDoc();
                                break;
                            default:
                                Log.i(Log.TAG_SYNC, "%s: could not save remote checkpoint: %s", this, e);
                                // TODO: On 401 or 403, and this is a pull, remember that remote
                                // TODo: is read-only & don't attempt to read its checkpoint next time.
                                break;
                        }
                    } else {
                        // Saved checkpoint:
                        Map<String, Object> response = (Map<String, Object>) result;
                        body.put("_rev", response.get("rev"));
                        remoteCheckpoint = body;
                        if (db != null && db.isOpen()) {
                            Log.d(Log.TAG_SYNC,
                                    "%s: saved remote checkpoint, updating local checkpoint. RemoteCheckpoint: %s",
                                    this, remoteCheckpoint);
                            setLastSequenceFromWorkExecutor(lastSequence, checkpointID);
                        } else {
                            Log.w(Log.TAG_SYNC, "%s: Database is null or closed, not calling db.setLastSequence() ", this);
                        }
                    }
                } finally {
                    savingCheckpoint = false;
                    if (overdueForCheckpointSave) {
                        Log.i(Log.TAG_SYNC, "%s: overdueForCheckpointSave == true, calling saveLastSequence()", this);
                        overdueForCheckpointSave = false;
                        saveLastSequence();
                    }
                }
            }
        });
        pendingFutures.add(future);
    }
1271465
@Override
    public void afterCompletion(int status)
    {
        final boolean isTraceOn = TraceComponent.isAnyTracingEnabled();

        if (isTraceOn && tc.isEntryEnabled())
            Tr.entry(tc, "afterCompletion : " + status + " : " + this);

        closeTxEntityManager(ivEm, true);

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