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())));
 }