private void testLockMigration(int nodeThatPuts) throws Exception {
    Map<Object, DummyTransaction> key2Tx = new HashMap<Object, DummyTransaction>();
    for (int i = 0; i < NUM_KEYS; i++) {
      Object key = getKeyForCache(0);
      if (key2Tx.containsKey(key)) continue;

      dummyTm(nodeThatPuts).begin();
      cache(nodeThatPuts).put(key, key);
      DummyTransaction tx = dummyTm(nodeThatPuts).getTransaction();
      tx.runPrepare();
      dummyTm(nodeThatPuts).suspend();
      key2Tx.put(key, tx);

      assertLocked(0, key);
    }

    log.trace("Lock transfer happens here");

    addClusterEnabledCacheManager(dccc);
    waitForClusterToForm();

    Object migratedKey = null;
    ConsistentHash ch = advancedCache(2).getDistributionManager().getConsistentHash();
    for (Object key : key2Tx.keySet()) {
      if (ch.locatePrimaryOwner(key).equals(address(2))) {
        migratedKey = key;
        break;
      }
    }
    if (migratedKey == null) {
      log.trace("No key migrated to new owner.");
    } else {
      log.trace("migratedKey = " + migratedKey);
      dummyTm(2).begin();
      cache(2).put(migratedKey, "someValue");
      try {
        dummyTm(2).commit();
        fail("RollbackException should have been thrown here.");
      } catch (RollbackException e) {
        // expected
      }
    }

    log.trace("About to commit existing transactions.");

    log.trace("Committing the tx to the new node.");
    for (Transaction tx : key2Tx.values()) {
      tm(nodeThatPuts).resume(tx);
      dummyTm(nodeThatPuts).getTransaction().runCommitTx();
    }

    for (Object key : key2Tx.keySet()) {
      Object value =
          getValue(
              key); // make sure that data from the container, just to make sure all replicas are
                    // correctly set
      assertEquals(key, value);
    }
  }
  public void testXidReturnedOnlyOnce() throws Throwable {
    DummyTransaction dummyTransaction1 = beginAndSuspendTx(this.cache(3));
    prepareTransaction(dummyTransaction1);
    manager(3).stop();
    TestingUtil.blockUntilViewsReceived(60000, false, cache(0), cache(1), cache(2));

    DummyTransaction dummyTransaction = beginAndSuspendTx(this.cache(0));
    Xid[] recover =
        dummyTransaction
            .firstEnlistedResource()
            .recover(XAResource.TMSTARTRSCAN | XAResource.TMENDRSCAN);
    assertEquals(recover.length, 1);
    assertEquals(dummyTransaction1.getXid(), recover[0]);
  }
  protected void doTest(final SplitMode splitMode, boolean txFail, boolean discard)
      throws Exception {
    waitForClusterToForm(OPTIMISTIC_TX_CACHE_NAME);

    final KeyInfo keyInfo = createKeys(OPTIMISTIC_TX_CACHE_NAME);
    final Cache<Object, String> originator = cache(0, OPTIMISTIC_TX_CACHE_NAME);
    final FilterCollection filterCollection =
        createFilters(OPTIMISTIC_TX_CACHE_NAME, discard, getCommandClass(), splitMode);

    Future<Void> put =
        fork(
            () -> {
              final DummyTransactionManager transactionManager =
                  (DummyTransactionManager) originator.getAdvancedCache().getTransactionManager();
              transactionManager.begin();
              keyInfo.putFinalValue(originator);
              final DummyTransaction transaction = transactionManager.getTransaction();
              transaction.runPrepare();
              transaction.runCommit(forceRollback());
              transaction.throwRollbackExceptionIfAny();
              return null;
            });

    filterCollection.await(30, TimeUnit.SECONDS);
    splitMode.split(this);
    filterCollection.unblock();

    try {
      put.get();
      assertFalse(txFail);
    } catch (ExecutionException e) {
      assertTrue(txFail);
    }

    checkLocksDuringPartition(splitMode, keyInfo, discard);

    mergeCluster(OPTIMISTIC_TX_CACHE_NAME);
    finalAsserts(OPTIMISTIC_TX_CACHE_NAME, keyInfo, txFail ? INITIAL_VALUE : FINAL_VALUE);
  }
Example #4
0
 protected void forgetWithInternalId(int cacheIndex) {
   long internalId = -1;
   for (RemoteTransaction rt : tt(1).getRemoteTransactions()) {
     RecoverableTransactionIdentifier a =
         (RecoverableTransactionIdentifier) rt.getGlobalTransaction();
     if (a.getXid().equals(tx.getXid())) {
       internalId = a.getInternalId();
     }
   }
   if (internalId == -1) throw new IllegalStateException();
   log.tracef("About to forget... %s", internalId);
   recoveryOps(cacheIndex).forget(internalId);
   assertEquals(tt(0).getRemoteTxCount(), 0);
   assertEquals(tt(1).getRemoteTxCount(), 0);
 }
  public void testPrimaryOwnerCrash() throws Exception {
    // cache 0 is the originator and backup, cache 1 is the primary owner
    StateSequencer ss = new StateSequencer();
    ss.logicalThread("main", "block_prepare", "crash_primary", "resume_prepare");

    tm(0).begin();
    cache(0).put("k", "v1");
    DummyTransaction tx1 = (DummyTransaction) tm(0).suspend();
    tx1.runPrepare();

    advanceOnInboundRpc(ss, cache(1), matchCommand(PrepareCommand.class).build())
        .before("block_prepare", "resume_prepare");

    Future<DummyTransaction> tx2Future =
        fork(
            () -> {
              tm(0).begin();
              cache(0).put("k", "v2");
              DummyTransaction tx2 = (DummyTransaction) tm(0).suspend();
              tx2.runPrepare();
              return tx2;
            });

    ss.enter("crash_primary");
    killMember(1);
    ss.exit("crash_primary");

    DummyTransaction tx2 = tx2Future.get(10, SECONDS);
    try {
      tx2.runCommit(false);
      fail("tx2 should not be able to commit");
    } catch (Exception e) {
      log.tracef(e, "Received expected exception");
    }

    tx1.runCommit(false);
  }
Example #6
0
 private void forgetWithXid(int nodeIndex) {
   Xid xid = tx.getXid();
   recoveryOps(nodeIndex)
       .forget(xid.getFormatId(), xid.getGlobalTransactionId(), xid.getBranchQualifier());
   assertEquals(tt(1).getRemoteTxCount(), 0); // make sure tx has been removed
 }
Example #7
0
 public void testInternalIdOnSameNode() throws Exception {
   Xid xid = tx.getXid();
   recoveryOps(0)
       .forget(xid.getFormatId(), xid.getGlobalTransactionId(), xid.getBranchQualifier());
   assertEquals(tt(1).getRemoteTxCount(), 0); // make sure tx has been removed
 }