@Override
  public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command)
      throws Throwable {
    wrapEntriesForPrepare(ctx, command);
    EntryVersionsMap newVersionData = null;
    if (ctx.isOriginLocal()
        && !((LocalTransaction) ctx.getCacheTransaction()).isFromStateTransfer())
      newVersionData =
          cdl.createNewVersionsAndCheckForWriteSkews(
              versionGenerator, ctx, (VersionedPrepareCommand) command);

    Object retval = invokeNextInterceptor(ctx, command);

    if (!ctx.isOriginLocal())
      newVersionData =
          cdl.createNewVersionsAndCheckForWriteSkews(
              versionGenerator, ctx, (VersionedPrepareCommand) command);
    if (command.isOnePhaseCommit())
      ctx.getCacheTransaction()
          .setUpdatedEntryVersions(((VersionedPrepareCommand) command).getVersionsSeen());

    if (newVersionData != null) retval = newVersionData;
    if (command.isOnePhaseCommit()) commitContextEntries(ctx, null);
    return retval;
  }
  @Override
  public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command)
      throws Throwable {
    Object retVal = invokeNextInterceptor(ctx, command);

    boolean sync = isSynchronous(ctx);

    if (shouldInvokeRemoteTxCommand(ctx)) {
      int newCacheViewId = -1;
      stateTransferLock.waitForStateTransferToEnd(ctx, command, newCacheViewId);

      if (command.isOnePhaseCommit())
        flushL1Caches(ctx); // if we are one-phase, don't block on this future.

      Collection<Address> recipients = dm.getAffectedNodes(ctx.getAffectedKeys());
      prepareOnAffectedNodes(ctx, command, recipients, sync);

      ((LocalTxInvocationContext) ctx).remoteLocksAcquired(recipients);
    } else if (isL1CacheEnabled
        && command.isOnePhaseCommit()
        && !ctx.isOriginLocal()
        && !ctx.getLockedKeys().isEmpty()) {
      // We fall into this block if we are a remote node, happen to be the primary data owner and
      // have locked keys.
      // it is still our responsibility to invalidate L1 caches in the cluster.
      flushL1Caches(ctx);
    }
    return retVal;
  }
  @Override
  public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command)
      throws Throwable {
    GMUPrepareCommand spc = convert(command, GMUPrepareCommand.class);

    if (ctx.isOriginLocal()) {
      spc.setVersion(ctx.getTransactionVersion());
      spc.setReadSet(ctx.getReadSet());
    } else {
      ctx.setTransactionVersion(spc.getPrepareVersion());
    }

    wrapEntriesForPrepare(ctx, command);
    performValidation(ctx, spc);

    Object retVal = invokeNextInterceptor(ctx, command);

    if (ctx.isOriginLocal() && command.getModifications().length > 0) {
      EntryVersion commitVersion =
          calculateCommitVersion(
              ctx.getTransactionVersion(),
              versionGenerator,
              cll.getWriteOwners(ctx.getCacheTransaction()));
      ctx.setTransactionVersion(commitVersion);
    } else {
      retVal = ctx.getTransactionVersion();
    }

    if (command.isOnePhaseCommit()) {
      commitContextEntries.commitContextEntries(ctx);
    }

    return retVal;
  }
 @Override
 public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command)
     throws Throwable {
   if (isStoreEnabled()) {
     if (getLog().isTraceEnabled())
       getLog().trace("Transactional so don't put stuff in the cache store yet.");
     prepareCacheLoader(ctx, command.getGlobalTransaction(), ctx, command.isOnePhaseCommit());
   }
   return invokeNextInterceptor(ctx, command);
 }
    @Override
    public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command)
        throws Throwable {
      boolean isTransactional = isTransactional();
      if (isTransactional) {

        // Sanity check -- if the remote tx doesn't have modifications, it never should have been
        // propagated!
        if (!command.hasModifications()) {
          throw new IllegalStateException("TxInvocationContext has no modifications!");
        }

        replayModificationsInTransaction(command, command.isOnePhaseCommit());
      } else {
        replayModifications(command);
      }
      return null;
    }
 /**
  * total order condition: only commits when it is remote context and the prepare has the flag 1PC
  * set
  *
  * @param command the prepare command
  * @param ctx the invocation context
  * @return true if the modification should be committed, false otherwise
  */
 protected boolean shouldCommitDuringPrepare(PrepareCommand command, TxInvocationContext ctx) {
   boolean isTotalOrder = cacheConfiguration.transaction().transactionProtocol().isTotalOrder();
   return isTotalOrder
       ? command.isOnePhaseCommit() && (!ctx.isOriginLocal() || !command.hasModifications())
       : command.isOnePhaseCommit();
 }