private EmbeddedTransaction newTx(Xid xid) { EmbeddedTransaction tx = new EmbeddedTransaction(EmbeddedTransactionManager.getInstance()); tx.setXid(xid); return tx; }
@Override public TransactionStatus getStatus() { try { EmbeddedTransaction transaction = tm.getTransaction(); return transaction == null ? TransactionStatus.NOT_ACTIVE : StatusTranslator.translate(transaction.getStatus()); } catch (SystemException e) { throw new RuntimeException(e); } }
@Override public void registerSynchronization(Synchronization synchronization) { try { BatchModeTransactionManager.getInstance().getTransaction().registerSynchronization(synchronization); } catch (RollbackException e) { throw new RuntimeException(e); } catch (SystemException e) { throw new RuntimeException(e); } } };
public void testNumberOfLocksHeld() throws Exception { EmbeddedTransactionManager tm = (EmbeddedTransactionManager) tm(); tm.begin(); cache.put("key", "value"); tm.getTransaction().runPrepare(); assertAttributeValue("NumberOfLocksHeld", 1); tm.getTransaction().runCommit(false); assertAttributeValue("NumberOfLocksHeld", 0); }
public void testReplay() throws Exception { assertClusterSize("Wrong cluster size", 3); final Object key = new MagicKey(cache(0), cache(1)); final Cache<Object, Object> newBackupOwnerCache = cache(2); final TxCommandInterceptor interceptor = TxCommandInterceptor.inject(newBackupOwnerCache); EmbeddedTransactionManager transactionManager = (EmbeddedTransactionManager) tm(0); transactionManager.begin(); cache(0).put(key, VALUE); final EmbeddedTransaction transaction = transactionManager.getTransaction(); transaction.runPrepare(); assertEquals("Wrong transaction status before killing backup owner.", Status.STATUS_PREPARED, transaction.getStatus()); //now, we kill cache(1). the transaction is prepared in cache(1) and it should be forward to cache(2) killMember(1); checkIfTransactionExists(newBackupOwnerCache); assertEquals("Wrong transaction status after killing backup owner.", Status.STATUS_PREPARED, transaction.getStatus()); transaction.runCommit(false); assertNoTransactions(); assertEquals("Wrong number of prepares!", 1, interceptor.numberPrepares.get()); assertEquals("Wrong number of commits!", 1, interceptor.numberCommits.get()); assertEquals("Wrong number of rollbacks!", 0, interceptor.numberRollbacks.get()); checkKeyInDataContainer(key); }
protected void prepare() { EmbeddedTransactionManager dtm = (EmbeddedTransactionManager) tm(0); dtm.getTransaction().runPrepare(); }
private void completeLocal(PerCacheTxTable txTable, CacheXid cacheXid, EmbeddedTransaction tx, boolean commit) { try { tx.runCommit(!commit); } catch (HeuristicMixedException | HeuristicRollbackException | RollbackException e) { //embedded tx cleanups everything //TODO log } finally { txTable.removeLocalTx(cacheXid.getXid()); } onTransactionCompleted(cacheXid); }
@BeforeMethod public void setUp() throws XAException { Cache mockCache = mock(Cache.class); Configuration configuration = new ConfigurationBuilder().build(); XaTransactionTable txTable = new XaTransactionTable(); txCoordinator = new TransactionCoordinator(); TestingUtil.inject(txTable, configuration, txCoordinator, TransactionOriginatorChecker.LOCAL); txTable.start(); txTable.startXidMapping(); TransactionFactory gtf = new TransactionFactory(); gtf.init(false, false, true, false); GlobalTransaction globalTransaction = gtf.newGlobalTransaction(null, false); EmbeddedBaseTransactionManager tm = new EmbeddedBaseTransactionManager(); localTx = new LocalXaTransaction(new EmbeddedTransaction(tm), globalTransaction, false, 1, 0); xid = new EmbeddedXid(uuid); InvocationContextFactory icf = new TransactionalInvocationContextFactory(); CommandsFactory commandsFactory = mock(CommandsFactory.class); AsyncInterceptorChain invoker = mock(AsyncInterceptorChain.class); TestingUtil.inject(txCoordinator, commandsFactory, icf, invoker, txTable, configuration); xaAdapter = new TransactionXaAdapter(localTx, txTable); xaAdapter.start(xid, 0); }
/** * Rollbacks the transaction if an exception happens during the transaction execution. */ public int rollback() { //log rolling back loggingDecision(false); //perform rollback try { tx.rollback(); } catch (SystemException e) { //ignore exception (heuristic exceptions) //TODO logging } finally { perCacheTxTable.removeLocalTx(xid); } //log rolled back loggingCompleted(false); return XAException.XA_RBROLLBACK; }
assert inDoubtTransactions.contains(t1_1.getXid()); assert inDoubtTransactions.contains(t1_2.getXid()); assert inDoubtTransactions.contains(t1_3.getXid()); assert inDoubtTransactions.contains(t1_1.getXid()); assert inDoubtTransactions.contains(t1_2.getXid()); assert inDoubtTransactions.contains(t1_3.getXid()); t1_4.firstEnlistedResource().forget(t1_1.getXid()); log.info("returned"); eventually(() -> rm(cache(0)).getInDoubtTransactionInfo().size() == 2); inDoubtTransactions = rm(cache(0)).getInDoubtTransactions(); assertEquals(2, inDoubtTransactions.size()); assert inDoubtTransactions.contains(t1_2.getXid()); assert inDoubtTransactions.contains(t1_3.getXid()); t1_4.firstEnlistedResource().forget(t1_2.getXid()); t1_4.firstEnlistedResource().forget(t1_3.getXid()); eventually(() -> rm(cache(0)).getInDoubtTransactionInfo().size() == 0); assertEquals(0, rm(cache(0)).getInDoubtTransactionInfo().size());
static void assertPrepared(int count, EmbeddedTransaction... tx) throws XAException { for (EmbeddedTransaction dt : tx) { TransactionXaAdapter xaRes = (TransactionXaAdapter) dt.firstEnlistedResource(); assertEquals(count, xaRes.recover(XAResource.TMSTARTRSCAN | XAResource.TMENDRSCAN).length); } }
public void testReadOnlyResource() throws Exception { //test for ISPN-2813 EmbeddedTransactionManager transactionManager = EmbeddedTransactionManager.getInstance(); transactionManager.begin(); cacheManager.<String, String>getCache(SYNC_CACHE_NAME).put(KEY, VALUE); cacheManager.<String, String>getCache(XA_CACHE_NAME).put(KEY, VALUE); transactionManager.getTransaction().enlistResource(new ReadOnlyXaResource()); transactionManager.commit(); assertData(); assertNoTxInAllCaches(); assertNull(transactionManager.getTransaction()); }
public void testLocksOnPutData() throws Exception { LockTestData tl = lockTestData; Cache<String, String> cache = tl.cache; TransactionManager tm = tl.tm; tm.begin(); cache.putAll(Collections.singletonMap("k", "v")); assertEquals("v", cache.get("k")); final EmbeddedTransaction tx = ((EmbeddedTransactionManager) tm).getTransaction(); assertTrue(tx.runPrepare()); assertLocked("k"); tx.runCommit(false); assertNoLocks(); tm.begin(); assertEquals("v", cache.get("k")); assertNoLocks(); tm.commit(); assertNoLocks(); }
private void performTest(Operation operation) throws Exception { assertClusterSize("Wrong number of caches.", 4); final Object key = new MagicKey(cache(0), cache(1), cache(2)); //init operation.init(cache(0), key); final EmbeddedTransactionManager transactionManager = (EmbeddedTransactionManager) tm(0); transactionManager.begin(); operation.perform(cache(0), key); final EmbeddedTransaction transaction = transactionManager.getTransaction(); transaction.runPrepare(); assertEquals("Wrong transaction status before killing backup owner.", Status.STATUS_PREPARED, transaction.getStatus()); //now, we kill cache(1). the transaction is prepared in cache(1) and it should be forward to cache(3) killMember(1); assertEquals("Wrong transaction status after killing backup owner.", Status.STATUS_PREPARED, transaction.getStatus()); transaction.runCommit(false); for (Cache<Object, Object> cache : caches()) { //all the caches are owner operation.check(cache, key, valueOf(address(cache))); } }
/** * Prepares the transaction. * * @param onePhaseCommit {@code true} if one phase commit. * @return the {@link javax.transaction.xa.XAResource#XA_OK} if successful prepared, otherwise one of the {@link * javax.transaction.xa.XAException} error codes. */ public int prepare(boolean onePhaseCommit) { Status status = loggingPreparing(); if (status != Status.OK) { //error, marked_*, no_transaction code (other node changed the state). we simply reply with rollback return XAException.XA_RBROLLBACK; } boolean prepared = tx.runPrepare(); if (prepared) { if (onePhaseCommit) { return onePhaseCommitTransaction(); } else { status = loggingPrepared(); return status == Status.OK ? XAResource.XA_OK : XAException.XA_RBROLLBACK; } } else { //Infinispan automatically rollbacks the transaction //we try to update the state and we don't care about the response. loggingCompleted(false); perCacheTxTable.removeLocalTx(xid); return XAException.XA_RBROLLBACK; } }
private int onePhaseCommitTransaction() { if (loggingDecision(true) != Status.OK) { //we failed to update the global cache return XAException.XAER_RMERR; } try { tx.runCommit(false); return loggingCompleted(true) == Status.OK ? XAResource.XA_OK : XAException.XAER_RMERR; //we failed to update the global cache. } catch (HeuristicMixedException | HeuristicRollbackException | RollbackException e) { //Infinispan automatically rollbacks it loggingCompleted(false); return XAException.XA_RBROLLBACK; } }
protected void rollback() { EmbeddedTransactionManager dtm = (EmbeddedTransactionManager) tm(); try { dtm.getTransaction().rollback(); } catch (SystemException e) { throw new RuntimeException(e); } }
public void testXidReturnedOnlyOnce() throws Throwable { EmbeddedTransaction dummyTransaction1 = beginAndSuspendTx(this.cache(3)); prepareTransaction(dummyTransaction1); manager(3).stop(); TestingUtil.blockUntilViewsReceived(60000, false, cache(0), cache(1), cache(2)); TestingUtil.waitForNoRebalance(cache(0), cache(1), cache(2)); EmbeddedTransaction dummyTransaction = beginAndSuspendTx(this.cache(0)); Xid[] recover = dummyTransaction.firstEnlistedResource().recover(XAResource.TMSTARTRSCAN | XAResource.TMENDRSCAN); assertEquals(recover.length,1); assertEquals(dummyTransaction1.getXid(), recover[0]); } }
public static void prepareTransaction(EmbeddedTransaction suspend1) { TransactionXaAdapter xaResource = (TransactionXaAdapter) suspend1.firstEnlistedResource(); try { xaResource.prepare(xaResource.getLocalTransaction().getXid()); } catch (XAException e) { throw new RuntimeException(e); } }
public void testLocksOnRemoveNonexistent() throws Exception { LockTestData tl = lockTestData; Cache<String, String> cache = tl.cache; EmbeddedTransactionManager tm = tl.tm; assert !cache.containsKey("k") : "Should not exist"; tm.begin(); cache.remove("k"); tm.getTransaction().runPrepare(); assertLocked("k"); tm.getTransaction().runCommit(false); assert !cache.containsKey("k") : "Should not exist"; assertNoLocks(); }