protected final void releaseLocksForCompletedTransaction(LocalTransaction localTransaction) { final GlobalTransaction gtx = localTransaction.getGlobalTransaction(); txTable.removeLocalTransaction(localTransaction); if (isClustered()) { removeTransactionInfoRemotely(localTransaction, gtx); } }
private void addException(Exception e, GlobalTransaction globalTransaction) { // this is not the most efficient way to do it, but it should have a lower number of local // transactions for (LocalTransaction localTransaction : transactionTable.getLocalTransactions()) { if (localTransaction.getGlobalTransaction().equals(globalTransaction)) { // TODO revisit this! // localTransaction.addException(e, true); break; } } }
private void applyTransactions(Address sender, Collection<TransactionInfo> transactions) { log.debugf( "Applying %d transactions for cache %s transferred from node %s", transactions.size(), cacheName, sender); if (isTransactional) { for (TransactionInfo transactionInfo : transactions) { CacheTransaction tx = transactionTable.getLocalTransaction(transactionInfo.getGlobalTransaction()); if (tx == null) { tx = transactionTable.getRemoteTransaction(transactionInfo.getGlobalTransaction()); if (tx == null) { tx = transactionTable.getOrCreateRemoteTransaction( transactionInfo.getGlobalTransaction(), transactionInfo.getModifications()); ((RemoteTransaction) tx).setMissingLookedUpEntries(true); } } for (Object key : transactionInfo.getLockedKeys()) { tx.addBackupLockForKey(key); } } } }
private void runAssertion(CacheOperation operation) throws NotSupportedException, SystemException, HeuristicMixedException, HeuristicRollbackException, InvalidTransactionException, RollbackException { txStatus.reset(); tm.begin(); cache(1).put("k1", "v1"); Transaction k1LockOwner = tm.suspend(); assert lm1.isLocked("k1"); assertEquals(1, txTable1.getLocalTxCount()); tm.begin(); cache(0).put("k2", "v2"); assert lm0.isLocked("k2"); assert !lm1.isLocked("k2"); operation.execute(); assertEquals(1, txTable1.getLocalTxCount()); assertEquals(1, txTable0.getLocalTxCount()); try { tm.commit(); assert false; } catch (RollbackException re) { // expected } assert txStatus.teReceived; assert txStatus.isTxInTableAfterTeOnPrepare; // expect 1 as k1 is locked by the other tx assertEquals( txStatus.numLocksAfterTeOnPrepare, 1, "This would make sure that locks are being released quickly, not waiting for a remote rollback to happen"); assertEquals(0, txTable0.getLocalTxCount()); assertEquals(1, txTable1.getLocalTxCount()); log.trace("Right before second commit"); tm.resume(k1LockOwner); tm.commit(); assertEquals("v1", cache(0).get("k1")); assertEquals("v1", cache(1).get("k1")); assertEquals(0, txTable1.getLocalTxCount()); assertEquals(0, txTable1.getLocalTxCount()); assertEquals(0, lm0.getNumberOfLocksHeld()); assertEquals(0, lm1.getNumberOfLocksHeld()); }
/** @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); } } }
private boolean isOngoingTransaction(InvocationContext ctx) throws SystemException { return ctx.isInTxScope() && (txTable.containsLocalTx(tm.getTransaction()) || (!ctx.isOriginLocal() && txTable.containRemoteTx(((TxInvocationContext) ctx).getGlobalTransaction()))); }