@Override public Object visitCommitCommand(TxInvocationContext ctx, CommitCommand command) throws Throwable { if (ctx.getCacheTransaction() instanceof RemoteTransaction) { // If a commit is received for a transaction that doesn't have its 'lookedUpEntries' populated // we know for sure this transaction is 2PC and was received via state transfer but the // preceding PrepareCommand // was not received by local node because it was executed on the previous key owners. We need // to re-prepare // the transaction on local node to ensure its locks are acquired and lookedUpEntries is // properly populated. RemoteTransaction remoteTx = (RemoteTransaction) ctx.getCacheTransaction(); if (remoteTx.isMissingLookedUpEntries()) { remoteTx.setMissingLookedUpEntries(false); PrepareCommand prepareCommand; if (useVersioning) { prepareCommand = commandFactory.buildVersionedPrepareCommand( ctx.getGlobalTransaction(), ctx.getModifications(), false); } else { prepareCommand = commandFactory.buildPrepareCommand( ctx.getGlobalTransaction(), ctx.getModifications(), false); } commandFactory.initializeReplicableCommand(prepareCommand, true); prepareCommand.setOrigin(ctx.getOrigin()); log.tracef( "Replaying the transactions received as a result of state transfer %s", prepareCommand); prepareCommand.perform(null); } } return handleTxCommand(ctx, command); }
public void applyRemoteTxLog(List<WriteCommand> commands) { for (WriteCommand cmd : commands) { try { // this is a remotely originating tx cf.initializeReplicableCommand(cmd, true); InvocationContext ctx = icc.createInvocationContext(); ctx.setFlags(SKIP_REMOTE_LOOKUP, CACHE_MODE_LOCAL, SKIP_SHARED_CACHE_STORE, SKIP_LOCKING); interceptorChain.invoke(ctx, cmd); } catch (Exception e) { log.exceptionWhenReplaying(cmd, e); } } }
@Override public void initializeReplicableCommand(ReplicableCommand command, boolean isRemote) { log.tracef("Received command %s", command); receivedCommands.add(command); if (isRemote) { remoteCommandsReceived.incrementAndGet(); if (toBlock != null && command.getClass().isAssignableFrom(toBlock)) { blockTypeCommandsReceived.incrementAndGet(); try { gate.await(); log.tracef("gate is opened, processing the lock cleanup: %s", command); } catch (InterruptedException e) { throw new RuntimeException(e); } } } actual.initializeReplicableCommand(command, isRemote); }