private void replayModificationsInTransaction(PrepareCommand command, boolean onePhaseCommit) throws Throwable { TransactionManager tm = txManager(); boolean replaySuccessful = false; try { tm.begin(); replayModifications(command); replaySuccessful = true; } finally { LocalTransaction localTx = txTable().getLocalTransaction(tm.getTransaction()); if (localTx != null) { // possible for the tx to be null if we got an exception during applying // modifications localTx.setFromRemoteSite(true); if (onePhaseCommit) { if (replaySuccessful) { log.tracef( "Committing remotely originated tx %s as it is 1PC", command.getGlobalTransaction()); tm.commit(); } else { log.tracef("Rolling back remotely originated tx %s", command.getGlobalTransaction()); tm.rollback(); } } else { // Wait for a remote commit/rollback. remote2localTx.put(command.getGlobalTransaction(), localTx.getGlobalTransaction()); tm.suspend(); } } } }
@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; }
public static Object prepare( TxInvocationContext txInvocationContext, PrepareCommand prepareCommand, TotalOrderRpcInterceptor interceptor) throws Throwable { if (log.isTraceEnabled()) { log.tracef("Preparing transaction %s", prepareCommand.getGlobalTransaction().prettyPrint()); } try { Object result = interceptor.visitPrepare(txInvocationContext, prepareCommand); if (log.isTraceEnabled()) { log.tracef( "Successful prepare of transaction %s", prepareCommand.getGlobalTransaction().prettyPrint()); } return result; } catch (CacheException cacheException) { Throwable cause = cacheException.getCause(); if (cause instanceof StateTransferException) { if (log.isTraceEnabled()) { log.tracef( "Transaction %s should be re-prepare", prepareCommand.getGlobalTransaction().prettyPrint()); } throw (StateTransferException) cause; } else { if (log.isTraceEnabled()) { log.tracef( "Error preparing transaction %s: %s", prepareCommand.getGlobalTransaction().prettyPrint(), cacheException.getCause()); } throw cacheException; } } }
@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); }
@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); }
protected final void wrapEntriesForPrepare(TxInvocationContext ctx, PrepareCommand command) throws Throwable { if (!ctx.isOriginLocal() || command.isReplayEntryWrapping()) { for (WriteCommand c : command.getModifications()) { c.acceptVisitor(ctx, entryWrappingVisitor); if (c.hasFlag(Flag.PUT_FOR_X_SITE_STATE_TRANSFER)) { ctx.getCacheTransaction().setStateTransferFlag(Flag.PUT_FOR_X_SITE_STATE_TRANSFER); } } } }
// We need to intercept PrepareCommand, not InvalidateCommand since the interception takes // place beforeQuery EntryWrappingInterceptor and the PrepareCommand is multiplexed into // InvalidateCommands // as part of EntryWrappingInterceptor @Override public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command) throws Throwable { if (ctx.isOriginLocal()) { // We can't wait to commit phase to remove the entry locally (invalidations are processed in // 1pc // on remote nodes, so only local case matters here). The problem is that while the entry is // locked // reads still can take place and we can read outdated collection afterQuery reading updated // entity // owning this collection from DB; when this happens, the version lock on entity cannot // protect // us against concurrent modification of the collection. Therefore, we need to remove the // entry // here (even without lock!) and let possible update happen in commit phase. for (WriteCommand wc : command.getModifications()) { if (wc instanceof InvalidateCommand) { // ISPN-5605 InvalidateCommand does not correctly implement getAffectedKeys() for (Object key : ((InvalidateCommand) wc).getKeys()) { dataContainer.remove(key); } } else { for (Object key : wc.getAffectedKeys()) { dataContainer.remove(key); } } } } else { for (WriteCommand wc : command.getModifications()) { if (wc instanceof InvalidateCommand) { // ISPN-5605 InvalidateCommand does not correctly implement getAffectedKeys() for (Object key : ((InvalidateCommand) wc).getKeys()) { if (log.isTraceEnabled()) { log.tracef("Invalidating key %s with lock owner %s", key, ctx.getLockOwner()); } putFromLoadValidator.beginInvalidatingKey(ctx.getLockOwner(), key); } } else { Set<Object> keys = wc.getAffectedKeys(); if (log.isTraceEnabled()) { log.tracef("Invalidating keys %s with lock owner %s", keys, ctx.getLockOwner()); } for (Object key : keys) { putFromLoadValidator.beginInvalidatingKey(ctx.getLockOwner(), key); } } } } return invokeNextInterceptor(ctx, command); }
@Override protected void prepareOnAffectedNodes( TxInvocationContext<?> ctx, PrepareCommand command, Collection<Address> recipients) { if (log.isTraceEnabled()) { log.tracef( "Total Order Anycast transaction %s with Total Order", command.getGlobalTransaction().globalId()); } if (!ctx.hasModifications()) { return; } if (!ctx.isOriginLocal()) { throw new IllegalStateException("Expected a local context while TO-Anycast prepare command"); } if (!(command instanceof VersionedPrepareCommand)) { throw new IllegalStateException( "Expected a Versioned Prepare Command in version aware component"); } try { KeysValidateFilter responseFilter = ctx.getCacheTransaction().hasModification(ClearCommand.class) || isSyncCommitPhase() ? null : new KeysValidateFilter(rpcManager.getAddress(), ctx.getAffectedKeys()); totalOrderPrepare(recipients, command, responseFilter); } finally { transactionRemotelyPrepared(ctx); } }
@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; }
@Override public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand cmd) throws Throwable { // first pass up chain Object o = invokeNextInterceptor(ctx, cmd); if (!ctx.isOriginLocal() || watchLocal) { markAsVisited(cmd); for (WriteCommand mod : cmd.getModifications()) markAsVisited(mod); } return o; }
@Override public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command) throws Throwable { if (ctx.isOriginLocal() && !isMaster() && (ctx.hasModifications() || command.hasModifications())) { throw new IllegalStateException( "Write transaction not allowed in Passive Replication, in backup node"); } return invokeNextInterceptor(ctx, command); }
@Override public CompletableFuture<Void> visitPrepareCommand( TxInvocationContext ctx, PrepareCommand command) throws Throwable { GlobalTransaction globalTransaction = command.getGlobalTransaction(); if (trace) { log.tracef( "Visit Prepare command %s. Is it local?. Transaction is %s", command, ctx.isOriginLocal(), globalTransaction.globalId()); } initStatsIfNecessary(ctx); cacheStatisticManager.onPrepareCommand(globalTransaction, ctx.isOriginLocal()); if (command.hasModifications()) { cacheStatisticManager.markAsWriteTransaction(globalTransaction, ctx.isOriginLocal()); } long start = timeService.time(); return ctx.onReturn( (rCtx, rCommand, rv, throwable) -> { if (throwable != null) { processWriteException(rCtx, globalTransaction, throwable); } else { long end = timeService.time(); updateTime( PREPARE_EXECUTION_TIME, NUM_PREPARE_COMMAND, start, end, globalTransaction, rCtx.isOriginLocal()); } if (((PrepareCommand) rCommand).isOnePhaseCommit()) { boolean local = rCtx.isOriginLocal(); boolean success = throwable == null; cacheStatisticManager.setTransactionOutcome( success, globalTransaction, rCtx.isOriginLocal()); cacheStatisticManager.terminateTransaction(globalTransaction, local, !local); } return null; }); }
/** * In case of a remotely originating transactions we don't have a chance to visit the single * commands but receive this "batch". We then need the before-apply snapshot of some types to * route the cleanup commands to the correct indexes. Note we don't need to visit the * CommitCommand as the indexing context is registered as a transaction sync. */ @Override public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command) throws Throwable { final WriteCommand[] writeCommands = command.getModifications(); final Object[] stateBeforePrepare = new Object[writeCommands.length]; for (int i = 0; i < writeCommands.length; i++) { final WriteCommand writeCommand = writeCommands[i]; if (writeCommand instanceof PutKeyValueCommand) { InternalCacheEntry internalCacheEntry = dataContainer.get(((PutKeyValueCommand) writeCommand).getKey()); stateBeforePrepare[i] = internalCacheEntry != null ? internalCacheEntry.getValue() : null; } else if (writeCommand instanceof PutMapCommand) { stateBeforePrepare[i] = getPreviousValues(((PutMapCommand) writeCommand).getMap().keySet()); } else if (writeCommand instanceof RemoveCommand) { InternalCacheEntry internalCacheEntry = dataContainer.get(((RemoveCommand) writeCommand).getKey()); stateBeforePrepare[i] = internalCacheEntry != null ? internalCacheEntry.getValue() : null; } else if (writeCommand instanceof ReplaceCommand) { InternalCacheEntry internalCacheEntry = dataContainer.get(((ReplaceCommand) writeCommand).getKey()); stateBeforePrepare[i] = internalCacheEntry != null ? internalCacheEntry.getValue() : null; } } final Object toReturn = super.visitPrepareCommand(ctx, command); if (ctx.isTransactionValid()) { final TransactionContext transactionContext = makeTransactionalEventContext(); for (int i = 0; i < writeCommands.length; i++) { final WriteCommand writeCommand = writeCommands[i]; if (writeCommand instanceof PutKeyValueCommand) { processPutKeyValueCommand( (PutKeyValueCommand) writeCommand, ctx, stateBeforePrepare[i], transactionContext); } else if (writeCommand instanceof PutMapCommand) { processPutMapCommand( (PutMapCommand) writeCommand, ctx, (Map<Object, Object>) stateBeforePrepare[i], transactionContext); } else if (writeCommand instanceof RemoveCommand) { processRemoveCommand( (RemoveCommand) writeCommand, ctx, stateBeforePrepare[i], transactionContext); } else if (writeCommand instanceof ReplaceCommand) { processReplaceCommand( (ReplaceCommand) writeCommand, ctx, stateBeforePrepare[i], transactionContext); } else if (writeCommand instanceof ClearCommand) { processClearCommand((ClearCommand) writeCommand, ctx, transactionContext); } } } return toReturn; }
@Override public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command) throws Throwable { Object retval = invokeNextInterceptor(ctx, command); log.tracef("Entering InvalidationInterceptor's prepare phase. Ctx flags are empty"); // fetch the modifications before the transaction is committed (and thus removed from the // txTable) if (shouldInvokeRemoteTxCommand(ctx)) { if (ctx.getTransaction() == null) throw new IllegalStateException("We must have an associated transaction"); List<WriteCommand> mods = Arrays.asList(command.getModifications()); broadcastInvalidateForPrepare(mods, ctx); } else { log.tracef("Nothing to invalidate - no modifications in the transaction."); } return retval; }
public static Collection<Response> totalOrderBroadcastPrepare( PrepareCommand prepareCommand, Collection<Address> target, Collection<Object> keysToValidate, RpcManager rpcManager, boolean waitOnlySelfDeliver, boolean syncCommitPhase, long timeout) { ResponseFilter filter; if (waitOnlySelfDeliver) { filter = new SelfDeliverFilter(rpcManager.getAddress()); } else if (keysToValidate != null && !syncCommitPhase) { filter = new KeyValidationFilter(keysToValidate, rpcManager.getAddress()); } else { filter = new AllResponsesFilter(); } if (log.isTraceEnabled()) { log.tracef( "Filter used by transaction %s is %s", prepareCommand.getGlobalTransaction().prettyPrint(), filter); } Map<Address, Response> responses = rpcManager.invokeRemotely( target, prepareCommand, ResponseMode.SYNCHRONOUS, timeout, true, filter, true); for (Response response : responses.values()) { if (response instanceof ExceptionResponse) { Exception e = ((ExceptionResponse) response).getException(); if (e instanceof CacheException) { throw (CacheException) e; } else { throw new CacheException(e); } } } return responses.values(); }
/** @param isRemote true if the command is deserialized and is executed remote. */ public void initializeReplicableCommand(ReplicableCommand c, boolean isRemote) { if (c == null) return; switch (c.getCommandId()) { case PutKeyValueCommand.COMMAND_ID: ((PutKeyValueCommand) c).init(notifier); break; case PutMapCommand.COMMAND_ID: ((PutMapCommand) c).init(notifier); break; case RemoveCommand.COMMAND_ID: ((RemoveCommand) c).init(notifier); break; case MultipleRpcCommand.COMMAND_ID: MultipleRpcCommand rc = (MultipleRpcCommand) c; rc.init(interceptorChain, icc); if (rc.getCommands() != null) for (ReplicableCommand nested : rc.getCommands()) { initializeReplicableCommand(nested, false); } break; case SingleRpcCommand.COMMAND_ID: SingleRpcCommand src = (SingleRpcCommand) c; src.init(interceptorChain, icc); if (src.getCommand() != null) initializeReplicableCommand(src.getCommand(), false); break; case InvalidateCommand.COMMAND_ID: InvalidateCommand ic = (InvalidateCommand) c; ic.init(notifier); break; case InvalidateL1Command.COMMAND_ID: InvalidateL1Command ilc = (InvalidateL1Command) c; ilc.init(configuration, distributionManager, notifier, dataContainer); break; case PrepareCommand.COMMAND_ID: PrepareCommand pc = (PrepareCommand) c; pc.init(interceptorChain, icc, txTable); pc.initialize(notifier, recoveryManager); if (pc.getModifications() != null) for (ReplicableCommand nested : pc.getModifications()) { initializeReplicableCommand(nested, false); } pc.markTransactionAsRemote(isRemote); if (configuration.isEnableDeadlockDetection() && isRemote) { DldGlobalTransaction transaction = (DldGlobalTransaction) pc.getGlobalTransaction(); transaction.setLocksHeldAtOrigin(pc.getAffectedKeys()); } break; case CommitCommand.COMMAND_ID: CommitCommand commitCommand = (CommitCommand) c; commitCommand.init(interceptorChain, icc, txTable); commitCommand.markTransactionAsRemote(isRemote); break; case RollbackCommand.COMMAND_ID: RollbackCommand rollbackCommand = (RollbackCommand) c; rollbackCommand.init(interceptorChain, icc, txTable); rollbackCommand.markTransactionAsRemote(isRemote); break; case ClearCommand.COMMAND_ID: ClearCommand cc = (ClearCommand) c; cc.init(notifier); break; case ClusteredGetCommand.COMMAND_ID: ClusteredGetCommand clusteredGetCommand = (ClusteredGetCommand) c; clusteredGetCommand.initialize(icc, this, interceptorChain, distributionManager); break; case LockControlCommand.COMMAND_ID: LockControlCommand lcc = (LockControlCommand) c; lcc.init(interceptorChain, icc, txTable); lcc.markTransactionAsRemote(isRemote); if (configuration.isEnableDeadlockDetection() && isRemote) { DldGlobalTransaction gtx = (DldGlobalTransaction) lcc.getGlobalTransaction(); RemoteTransaction transaction = txTable.getRemoteTransaction(gtx); if (transaction != null) { if (!configuration.getCacheMode().isDistributed()) { Set<Object> keys = txTable.getLockedKeysForRemoteTransaction(gtx); GlobalTransaction gtx2 = transaction.getGlobalTransaction(); ((DldGlobalTransaction) gtx2).setLocksHeldAtOrigin(keys); gtx.setLocksHeldAtOrigin(keys); } else { GlobalTransaction gtx2 = transaction.getGlobalTransaction(); ((DldGlobalTransaction) gtx2).setLocksHeldAtOrigin(gtx.getLocksHeldAtOrigin()); } } } break; case RehashControlCommand.COMMAND_ID: RehashControlCommand rcc = (RehashControlCommand) c; rcc.init(distributionManager, configuration, dataContainer, this); break; case GetInDoubtTransactionsCommand.COMMAND_ID: GetInDoubtTransactionsCommand gptx = (GetInDoubtTransactionsCommand) c; gptx.init(recoveryManager); break; case RemoveRecoveryInfoCommand.COMMAND_ID: RemoveRecoveryInfoCommand ftx = (RemoveRecoveryInfoCommand) c; ftx.init(recoveryManager); break; case MapReduceCommand.COMMAND_ID: MapReduceCommand mrc = (MapReduceCommand) c; mrc.init( this, interceptorChain, icc, distributionManager, cache.getAdvancedCache().getRpcManager().getAddress()); break; case DistributedExecuteCommand.COMMAND_ID: DistributedExecuteCommand dec = (DistributedExecuteCommand) c; dec.init(cache); break; case GetInDoubtTxInfoCommand.COMMAND_ID: GetInDoubtTxInfoCommand gidTxInfoCommand = (GetInDoubtTxInfoCommand) c; gidTxInfoCommand.init(recoveryManager); break; case CompleteTransactionCommand.COMMAND_ID: CompleteTransactionCommand ccc = (CompleteTransactionCommand) c; ccc.init(recoveryManager); break; default: ModuleCommandInitializer mci = moduleCommandInitializers.get(c.getCommandId()); if (mci != null) { mci.initializeReplicableCommand(c, isRemote); } else { if (trace) log.tracef("Nothing to initialize for command: %s", c); } } }
public PrepareCommand buildPrepareCommand( GlobalTransaction gtx, List<WriteCommand> modifications, boolean onePhaseCommit) { PrepareCommand command = new PrepareCommand(gtx, modifications, onePhaseCommit); command.setCacheName(cacheName); return command; }
private void replayModifications(PrepareCommand command) throws Throwable { for (WriteCommand c : command.getModifications()) { c.acceptVisitor(null, this); } }
/** @param isRemote true if the command is deserialized and is executed remote. */ @Override public void initializeReplicableCommand(ReplicableCommand c, boolean isRemote) { if (c == null) return; switch (c.getCommandId()) { case PutKeyValueCommand.COMMAND_ID: ((PutKeyValueCommand) c).init(notifier, configuration); break; case ReplaceCommand.COMMAND_ID: ((ReplaceCommand) c).init(notifier, configuration); break; case PutMapCommand.COMMAND_ID: ((PutMapCommand) c).init(notifier); break; case RemoveCommand.COMMAND_ID: ((RemoveCommand) c).init(notifier, configuration); break; case MultipleRpcCommand.COMMAND_ID: MultipleRpcCommand rc = (MultipleRpcCommand) c; rc.init(interceptorChain, icf); if (rc.getCommands() != null) for (ReplicableCommand nested : rc.getCommands()) { initializeReplicableCommand(nested, false); } break; case SingleRpcCommand.COMMAND_ID: SingleRpcCommand src = (SingleRpcCommand) c; src.init(interceptorChain, icf); if (src.getCommand() != null) initializeReplicableCommand(src.getCommand(), false); break; case InvalidateCommand.COMMAND_ID: InvalidateCommand ic = (InvalidateCommand) c; ic.init(notifier, configuration); break; case InvalidateL1Command.COMMAND_ID: InvalidateL1Command ilc = (InvalidateL1Command) c; ilc.init(configuration, distributionManager, notifier, dataContainer); break; case PrepareCommand.COMMAND_ID: case VersionedPrepareCommand.COMMAND_ID: case TotalOrderNonVersionedPrepareCommand.COMMAND_ID: case TotalOrderVersionedPrepareCommand.COMMAND_ID: PrepareCommand pc = (PrepareCommand) c; pc.init(interceptorChain, icf, txTable); pc.initialize(notifier, recoveryManager); if (pc.getModifications() != null) for (ReplicableCommand nested : pc.getModifications()) { initializeReplicableCommand(nested, false); } pc.markTransactionAsRemote(isRemote); if (configuration.deadlockDetection().enabled() && isRemote) { DldGlobalTransaction transaction = (DldGlobalTransaction) pc.getGlobalTransaction(); transaction.setLocksHeldAtOrigin(pc.getAffectedKeys()); } break; case CommitCommand.COMMAND_ID: case VersionedCommitCommand.COMMAND_ID: case TotalOrderCommitCommand.COMMAND_ID: case TotalOrderVersionedCommitCommand.COMMAND_ID: CommitCommand commitCommand = (CommitCommand) c; commitCommand.init(interceptorChain, icf, txTable); commitCommand.markTransactionAsRemote(isRemote); break; case RollbackCommand.COMMAND_ID: case TotalOrderRollbackCommand.COMMAND_ID: RollbackCommand rollbackCommand = (RollbackCommand) c; rollbackCommand.init(interceptorChain, icf, txTable); rollbackCommand.markTransactionAsRemote(isRemote); break; case ClearCommand.COMMAND_ID: ClearCommand cc = (ClearCommand) c; cc.init(notifier, dataContainer); break; case ClusteredGetCommand.COMMAND_ID: ClusteredGetCommand clusteredGetCommand = (ClusteredGetCommand) c; clusteredGetCommand.initialize( icf, this, entryFactory, interceptorChain, distributionManager, txTable, configuration.dataContainer().keyEquivalence()); break; case LockControlCommand.COMMAND_ID: LockControlCommand lcc = (LockControlCommand) c; lcc.init(interceptorChain, icf, txTable); lcc.markTransactionAsRemote(isRemote); if (configuration.deadlockDetection().enabled() && isRemote) { DldGlobalTransaction gtx = (DldGlobalTransaction) lcc.getGlobalTransaction(); RemoteTransaction transaction = txTable.getRemoteTransaction(gtx); if (transaction != null) { if (!configuration.clustering().cacheMode().isDistributed()) { Set<Object> keys = txTable.getLockedKeysForRemoteTransaction(gtx); GlobalTransaction gtx2 = transaction.getGlobalTransaction(); ((DldGlobalTransaction) gtx2).setLocksHeldAtOrigin(keys); gtx.setLocksHeldAtOrigin(keys); } else { GlobalTransaction gtx2 = transaction.getGlobalTransaction(); ((DldGlobalTransaction) gtx2).setLocksHeldAtOrigin(gtx.getLocksHeldAtOrigin()); } } } break; case StateRequestCommand.COMMAND_ID: ((StateRequestCommand) c).init(stateProvider); break; case StateResponseCommand.COMMAND_ID: ((StateResponseCommand) c).init(stateConsumer); break; case GetInDoubtTransactionsCommand.COMMAND_ID: GetInDoubtTransactionsCommand gptx = (GetInDoubtTransactionsCommand) c; gptx.init(recoveryManager); break; case TxCompletionNotificationCommand.COMMAND_ID: TxCompletionNotificationCommand ftx = (TxCompletionNotificationCommand) c; ftx.init(txTable, lockManager, recoveryManager, stateTransferManager); break; case MapCombineCommand.COMMAND_ID: MapCombineCommand mrc = (MapCombineCommand) c; mrc.init(mapReduceManager); break; case ReduceCommand.COMMAND_ID: ReduceCommand reduceCommand = (ReduceCommand) c; reduceCommand.init(mapReduceManager); break; case DistributedExecuteCommand.COMMAND_ID: DistributedExecuteCommand dec = (DistributedExecuteCommand) c; dec.init(cache); break; case GetInDoubtTxInfoCommand.COMMAND_ID: GetInDoubtTxInfoCommand gidTxInfoCommand = (GetInDoubtTxInfoCommand) c; gidTxInfoCommand.init(recoveryManager); break; case CompleteTransactionCommand.COMMAND_ID: CompleteTransactionCommand ccc = (CompleteTransactionCommand) c; ccc.init(recoveryManager); break; case ApplyDeltaCommand.COMMAND_ID: break; case CreateCacheCommand.COMMAND_ID: CreateCacheCommand createCacheCommand = (CreateCacheCommand) c; createCacheCommand.init(cache.getCacheManager()); break; case XSiteAdminCommand.COMMAND_ID: XSiteAdminCommand xSiteAdminCommand = (XSiteAdminCommand) c; xSiteAdminCommand.init(backupSender); break; case CancelCommand.COMMAND_ID: CancelCommand cancelCommand = (CancelCommand) c; cancelCommand.init(cancellationService); break; case XSiteStateTransferControlCommand.COMMAND_ID: XSiteStateTransferControlCommand xSiteStateTransferControlCommand = (XSiteStateTransferControlCommand) c; xSiteStateTransferControlCommand.initialize( xSiteStateProvider, xSiteStateConsumer, xSiteStateTransferManager); break; case XSiteStatePushCommand.COMMAND_ID: XSiteStatePushCommand xSiteStatePushCommand = (XSiteStatePushCommand) c; xSiteStatePushCommand.initialize(xSiteStateConsumer); break; case EntryRequestCommand.COMMAND_ID: EntryRequestCommand entryRequestCommand = (EntryRequestCommand) c; entryRequestCommand.init(entryRetriever); break; case EntryResponseCommand.COMMAND_ID: EntryResponseCommand entryResponseCommand = (EntryResponseCommand) c; entryResponseCommand.init(entryRetriever); break; case GetKeysInGroupCommand.COMMAND_ID: GetKeysInGroupCommand getKeysInGroupCommand = (GetKeysInGroupCommand) c; getKeysInGroupCommand.setGroupManager(groupManager); break; case ClusteredGetAllCommand.COMMAND_ID: ClusteredGetAllCommand clusteredGetAllCommand = (ClusteredGetAllCommand) c; clusteredGetAllCommand.init( icf, this, entryFactory, interceptorChain, txTable, configuration.dataContainer().keyEquivalence()); break; case StreamRequestCommand.COMMAND_ID: StreamRequestCommand streamRequestCommand = (StreamRequestCommand) c; streamRequestCommand.inject(localStreamManager); break; case StreamResponseCommand.COMMAND_ID: StreamResponseCommand streamResponseCommand = (StreamResponseCommand) c; streamResponseCommand.inject(clusterStreamManager); break; case StreamSegmentResponseCommand.COMMAND_ID: StreamSegmentResponseCommand streamSegmentResponseCommand = (StreamSegmentResponseCommand) c; streamSegmentResponseCommand.inject(clusterStreamManager); break; case RemoveExpiredCommand.COMMAND_ID: RemoveExpiredCommand removeExpiredCommand = (RemoveExpiredCommand) c; removeExpiredCommand.init(notifier, configuration); break; default: ModuleCommandInitializer mci = moduleCommandInitializers.get(c.getCommandId()); if (mci != null) { mci.initializeReplicableCommand(c, isRemote); } else { if (trace) log.tracef("Nothing to initialize for command: %s", c); } } }
/** * 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(); }