/*
Use this to lock persistently. Invoke indirectly by the API.

@param transaction
779899
final void cmdPersistLock(final PersistentTransaction transaction) throws SevereMessageStoreException
    {
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
            SibTr.entry(this, tc, "cmdPersistLock", new Object[] { "Item Link:   " + this, "Stream Link: " + _owningStreamLink, "Transaction: " + transaction });

        if (null != transaction)
        {
            boolean hasBecomeNonReleasable = false;
            synchronized (this)
            {
                if (ItemLinkState.STATE_LOCKED == _itemLinkState)
                {
                    _transactionId = transaction.getPersistentTranId();
                    hasBecomeNonReleasable = _declareNotDiscardable(_getAndAssertItem());
                    _itemLinkState = ItemLinkState.STATE_PERSISTING_LOCK;
                }
                else
                {
                    if (TraceComponent.isAnyTracingEnabled() && tc.isEventEnabled())
                        SibTr.event(this, tc, "Invalid Item state: " + _itemLinkState);
                    if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                        SibTr.exit(this, tc, "cmdPersistLock");
                    throw new StateException(_itemLinkState.toString());
                }
            }
            if (hasBecomeNonReleasable)
            {
                _declareNotReleasable();
            }
        }

        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
            SibTr.exit(this, tc, "cmdPersistLock");
    }
901166
@Override
    public void setTransactionTimeout(int timeout) throws SystemException
    {
        Transaction tx = threadLocal.get();
        if (tx == null)
        {
            timerThead.set(timeout);
        }
        else
        {
            if (log.isDebugEnabled())
                log.debug("Cannot reset running transaction:" + tx);
        }

    }
960443
private void executeLock( ITransaction transaction,
                              HttpServletRequest req,
                              HttpServletResponse resp ) throws LockFailedException, IOException, ServletException {

        // Mac OS lock request workaround
        if (macLockRequest) {
            logger.trace("DoLock.execute() : do workaround for user agent '" + userAgent + "'");

            doMacLockRequestWorkaround(transaction, req, resp);
        } else {
            // Getting LockInformation from request
            if (getLockInformation(req, resp)) {
                int depth = getDepth(req);
                int lockDuration = getTimeout(req);

                boolean lockSuccess = false;
                if (exclusive) {
                    lockSuccess = resourceLocks.exclusiveLock(transaction, path, lockOwner, depth, lockDuration);
                } else {
                    lockSuccess = resourceLocks.sharedLock(transaction, path, lockOwner, depth, lockDuration);
                }

                if (lockSuccess) {
                    // Locks successfully placed - return information about
                    LockedObject lo = resourceLocks.getLockedObjectByPath(transaction, path);
                    if (lo != null) {
                        generateXMLReport(resp, lo);
                    } else {
                        resp.sendError(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
                    }
                } else {
                    sendLockFailError(req, resp);

                    throw new LockFailedException();
                }
            } else {
                // information for LOCK could not be read successfully
                resp.setContentType("text/xml; charset=UTF-8");
                resp.sendError(WebdavStatus.SC_BAD_REQUEST);
            }
        }
    }
13413
private void executeUpdatesAsynchronous(DBTransaction transaction) {
        Collection<BoundStatement> mutations = getMutations(transaction);
        List<ResultSetFuture> futureList = new ArrayList<>(mutations.size());
        for(BoundStatement mutation: mutations) {
            ResultSetFuture future = m_dbservice.getSession().executeAsync(mutation);
            futureList.add(future);
        }
        m_logger.debug("Waiting for {} asynchronous futures", futureList.size());
        for (ResultSetFuture future : futureList) {
            future.getUninterruptibly();
        }
    }
489622
public void assignTransaction(TransactionImpl v)
   {
      txs.put(Long.valueOf(Thread.currentThread().getId()), v);
   }
652580
public final void preCommitRemove(final PersistentTransaction transaction) throws SevereMessageStoreException
    {
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
            SibTr.entry(this, tc, "preCommitRemove", transaction);

        synchronized (this)
        {
            SevereMessageStoreException ex = assertCanDelete(transaction);
            if (null != ex)
            {
                throw ex;
            }

            if ((_itemLinkState == ItemLinkState.STATE_REMOVING_EXPIRING)
                || (_itemLinkState == ItemLinkState.STATE_REMOVING_LOCKED)
                || (_itemLinkState == ItemLinkState.STATE_REMOVING_PERSISTENTLY_LOCKED)
                || (_itemLinkState == ItemLinkState.STATE_REMOVING_WITHOUT_LOCK))
            {
                _assertCorrectTransaction(transaction);
                _owningStreamLink._assertCanRemoveChildUnder(transaction);
            }
            else
            {
                if (TraceComponent.isAnyTracingEnabled() && tc.isEventEnabled())
                    SibTr.event(this, tc, "Invalid Item state: " + _itemLinkState);
                if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                    SibTr.exit(this, tc, "preCommitRemove");
                throw new StateException(_itemLinkState.toString());
            }

            getItem().eventPrecommitRemove(transaction);
        } // end sync

        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
            SibTr.exit(this, tc, "preCommitRemove");
    }
939808
protected void handleRollback(LocalTransaction transaction)
  {
    if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
      SibTr.entry(tc, "handleRollback", transaction);

    // Roll back the transaction if we created it.
    if (transaction != null)
    {
      try
      {
        transaction.rollback();
      }
      catch (SIException e)
      {
        // FFDC
        FFDCFilter.processException(
          e,
          "com.ibm.ws.sib.processor.impl.PtoPOutputHandler.handleRollback",
          "1:1644:1.241",
          this);

        SibTr.exception(tc, e);
      }
    }

    if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
      SibTr.exit(tc, "handleRollback");
  }
737614
public void prepare(PersistentTransaction transaction) throws PersistenceException, SevereMessageStoreException
    {
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.entry(this, tc, "prepare", "Transaction="+transaction);

        // Defect 363755
        if (!_available)
        {
            MessageStoreUnavailableException msue = new MessageStoreUnavailableException("Operation not possible as MessageStore is unavailable!");
            if (TraceComponent.isAnyTracingEnabled() && tc.isEventEnabled()) SibTr.event(this, tc, "Operation not possible as MessageStore is unavailable!");
            if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.exit(this, tc, "prepare");
            throw msue;
        }

        //Get the task list from the transaction
        TaskList taskList = (TaskList) transaction.getWorkList();

        PersistentTranId       xid = transaction.getPersistentTranId();
        TransactionState tranState = transaction.getTransactionState();
        int          numberOfTasks = taskList.countLinks();

        boolean requiresSyncPersistence = false;

        // Defect 530772
        boolean requiresSpillPersistence = false;

        // Defect 298584
        // Batching context will only be created if we
        // have synchronous work to do.
        BatchingContext syncBatch = null;
        List             syncList = null;

        if (taskList.hasStoreAlways() || taskList.hasStoreEventually() || taskList.hasStoreMaybe())
        {
            // We have synchronous work to do so
            // we need to build up a list of tasks.
            Iterator iterator = taskList.iterator();
            while (iterator.hasNext())
            {
                Operation          task = (Operation) iterator.next();
                Persistable persistable = task.getPersistable();

                // Defect 451518
                if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(this, tc, "Preparing Task: "+task);

                if (persistable != null && persistable.requiresPersistence())
                {
                    int     storageStrategy = persistable.getStorageStrategy();
                    TupleTypeEnum tupleType = persistable.getTupleType();

                    // Feature SIB0112i.ms.1
                    // We only need to persist our synchronous work at this point. If our
                    // transaction prepares successfully then at commit time we can make
                    // sure our STORE_MAYBE work is persisted.

                    // Defect 530772
                    // Are we a STORE_MAYBE Item? If so then we can be dispatched to the
                    // spill dispatcher. If not then we need to be persisted synchronously.
                    // This is to avoid adding complication to the spill dispatcher as it
                    // does not worry about the order in which things are persisted so an
                    // Item on a stream can be hardened to disk before the stream. This will
                    // not work in the filestore case.
                    if (tupleType != TupleTypeEnum.ITEM_STREAM &&
                        tupleType != TupleTypeEnum.REFERENCE_STREAM &&
                        storageStrategy == AbstractItem.STORE_MAYBE)
                    {
                        if (requiresSpillPersistence == false)
                        {
                            requiresSpillPersistence = true;
                        }
                    }
                    // If not we are synchronous.
                    else
                    {
                        // Defect 298584
                        // Only create our batching context once we know for sure
                        // that we have some synchronous work to do.
                        if (requiresSyncPersistence == false)
                        {
                            syncList  = new ArrayList(numberOfTasks);
                            syncBatch = new BatchingContextImpl(_objectManager, _permanentStore, transaction);
                            transaction.setBatchingContext(syncBatch);
                            requiresSyncPersistence = true;
                        }

                        //Associate the global tran id with the persistable
                        persistable.setPersistentTranId(xid);

                        task.persist(syncBatch, tranState);
                        syncList.add(persistable);
                    }
                }
            }
        }


        // Defect 530772
        // Check the health of the spill dispatcher to minimise the risk
        // of splitting a transaction.
        if (requiresSpillPersistence)
        {
            if (!_spillDispatcher.isHealthy())
            {
                // Defect 345250
                // The dispatcher is not currently accepting new work as it has
                // hit a problem. Details of the problem should have been output
                // to the logs by the dispatcher thread at the point where it
                // occurred.
                PersistenceException pe = new PersistenceException("SPILL_DISPATCHER_CANNOT_ACCEPT_WORK_SIMS1578");
                if (TraceComponent.isAnyTracingEnabled() && tc.isEventEnabled()) SibTr.event(this, tc, "The spill dispatcher cannot accept work!", pe);
                if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.exit(this, tc, "prepare");
                throw pe;
            }
        }

        // Feature SIB0112i.ms.1
        // We only have to do some work in prepare if we have
        // synchronous work to add to the file store.
        if (requiresSyncPersistence)
        {
            try
            {
                // As this is a prepare we use the addIndoubtXid()
                // method to inform the batching context that we only
                // wish to prepare during this executeUpdate() call.
                syncBatch.addIndoubtXID(xid);

                // Submit the batch and trigger the prepare in the
                // object manager.
                syncBatch.executeBatch();

                // If we get to this point then the prepare was successful, so we need to
                // notify the cache layer
                Iterator iterator = syncList.iterator();
                while (iterator.hasNext())
                {
                    Tuple tuple = (Tuple)iterator.next();

                    // Both these methods need to be called to indicate to the cache
                    // that it can soften its in-memory reference to the persistable
                    tuple.persistableOperationBegun();
                    tuple.persistableOperationCompleted();
                }
            }
            catch (PersistenceException pe)
            {
                com.ibm.ws.ffdc.FFDCFilter.processException(pe, "com.ibm.ws.sib.msgstore.persistence.objectManager.PersistableMessageStoreImpl.prepare", "1:1615:1.81.1.6", this);
                if (TraceComponent.isAnyTracingEnabled() && tc.isEventEnabled()) SibTr.event(this, tc, "Exception caught preparing transaction in object store!", pe);
                if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.exit(this, tc, "prepare");
                throw pe;
            }
        }

        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.exit(this, tc, "prepare");
    }
1374299
public final void commitInternal(final PersistentTransaction transaction) throws SevereMessageStoreException
    {
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.entry(this, tc, "commitInternal", transaction);

        getLink().commitRemove(transaction);

        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.exit(this, tc, "commitInternal");
    }
847885
private void applyUpdates(DBTransaction transaction) {
        if (transaction.getMutationsCount() == 0) {
            m_logger.debug("Skipping commit with no updates");
        } else if (m_dbservice.getParamBoolean("async_updates")) {
            executeUpdatesAsynchronous(transaction);
        } else {
            executeUpdatesSynchronous(transaction);
        }
    }
953534
public static void transaction(Runnable action, boolean readOnly) {
		Ctx ctx = Ctxs.get();
		boolean newContext = ctx == null;

		if (newContext) {
			ctx = Ctxs.open("transaction");
		}

		try {
			EntityManager em = ctx.persister();
			JPA.with(em).transactional(action, readOnly);

		} finally {
			if (newContext) {
				Ctxs.close();
			}
		}
	}
702862
@Override
    public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException,
            SecurityException, IllegalStateException, SystemException
    {
        if (!setRollBackOnly)
        {
            for (ResourceManager implementor : implementors)
            {
                if (implementor != null)
                {
                    implementor.doCommit();
                }
            }
            status = Status.STATUS_COMMITTED;
        }
        else
        {
            if (log.isDebugEnabled())
                log.debug("Transaction is set for rollback only, processing rollback.");

            for (ResourceManager implementor : implementors)
            {
                if (implementor != null)
                {
                    implementor.doRollback();
                    status = Status.STATUS_ROLLEDBACK;
                }
            }
        }

    }
336872
public boolean writeLock(TransactionImpl tx, Object obj)
    {
        LockEntry writer = getWriter(obj);
        if (writer == null)
        {
            if (setWriter(tx, obj))
                return true;
            else
                return writeLock(tx, obj);
        }
        if (writer.isOwnedBy(tx))
        {
            return true;    // If I'm the writer, then I can write.
        }
        return false;
    }
138045
public void runInRetryableTransaction(Runnable runnable)
    throws DataAccessException {
        TransactionWrapper transaction=null;
        try {
            transaction = startTransaction();
            runnable.run();
        } catch (Throwable e) {
            if (canRetryTransaction(e)) {
                transaction = (TransactionWrapper)initTransactionRetry(transaction);
                ((ProcessExecutor)getTransactionRetrier()).runInTransaction(runnable);
            }
            else
                throw e;
        } finally {
            stopTransaction(transaction);
        }
    }
296050
protected void modify(Transaction t) {
        try {
            this.lock.writeLock().lock();
            t.perform();
        } finally {
            this.lock.writeLock().unlock();
        }
    }
1054335
public void newTransactionHandler(PersistedTransaction tx, PersistedV2Key key) throws Exception {
        listenForUpdates(tx);
        tx.keyId = key.getId();
        tx.walletId = this.descriptor.getKey();
        tx.account = key.account;
        System.out.println("Incoming transaction captured in API service: " + tx.toString());
        transactionDAO.create(tx);
        WalletChange change = new WalletChange(tx.value, getBalance(), createKey(key.account).address, tx);
        WalletChangeMessage out = new WalletChangeMessage();
        out.setCommand(Command.BALANCE_CHANGE_RECEIVED);
        out.setKey(this.descriptor.key);
        out.setPayload(change);
        router.sendUpdate(this.descriptor.key, out);
    }
464893
@Override
    public void lock(Object entity, LockModeType lockMode)
    {
        if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
            Tr.debug(tc, "em.lock(" + entity + ',' + lockMode + ");\n" + toString());

        getEMInvocationInfo(true).lock(entity, lockMode);
    }