Search in sources :

Example 6 with ExecuteException

use of org.jboss.byteman.rule.exception.ExecuteException in project narayana by jbosstm.

the class TestCommitMarkableResourceFailAfterCommitOrphan method test.

@Test
@BMScript("commitMarkableResourceFailAfterCommit")
public void test() throws Exception {
    final JdbcDataSource dataSource = new JdbcDataSource();
    dataSource.setURL("jdbc:h2:mem:JBTMDB;MVCC=TRUE;DB_CLOSE_DELAY=-1");
    // Test code
    Utils.createTables(dataSource.getConnection());
    // We can't just instantiate one as we need to be using the
    // same one as
    // the transaction
    // manager would have used to mark the transaction for GC
    CommitMarkableResourceRecordRecoveryModule commitMarkableResourceRecoveryModule = null;
    Vector recoveryModules = manager.getModules();
    if (recoveryModules != null) {
        Enumeration modules = recoveryModules.elements();
        while (modules.hasMoreElements()) {
            RecoveryModule m = (RecoveryModule) modules.nextElement();
            if (m instanceof CommitMarkableResourceRecordRecoveryModule) {
                commitMarkableResourceRecoveryModule = (CommitMarkableResourceRecordRecoveryModule) m;
            } else if (m instanceof XARecoveryModule) {
                xarm = (XARecoveryModule) m;
                xarm.addXAResourceRecoveryHelper(new XAResourceRecoveryHelper() {

                    public boolean initialise(String p) throws Exception {
                        return true;
                    }

                    public XAResource[] getXAResources() throws Exception {
                        return new XAResource[] { xaResource };
                    }
                });
            }
        }
    }
    // final Object o = new Object();
    // synchronized (o) {
    Thread preCrash = new Thread(new Runnable() {

        public void run() {
            try (Connection localJDBCConnection = dataSource.getConnection()) {
                javax.transaction.TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
                tm.begin();
                localJDBCConnection.setAutoCommit(false);
                cmrResource = new JDBCConnectableResource(localJDBCConnection);
                tm.getTransaction().enlistResource(cmrResource);
                tm.getTransaction().enlistResource(xaResource);
                localJDBCConnection.createStatement().execute("INSERT INTO foo (bar) VALUES (1)");
                tm.commit();
            } catch (ExecuteException t) {
            } catch (Exception e) {
                e.printStackTrace();
                failed = true;
            } catch (Error e) {
            }
        }
    });
    preCrash.start();
    preCrash.join();
    assertFalse(failed);
    assertFalse(wasCommitted);
    assertFalse(wasRolledback);
    // The recovery module has to perform lookups
    new InitialContext().rebind("commitmarkableresource", dataSource);
    // Testing that we can find a AAC but that it won't be ignored in orphan detection so need CMRRM run
    commitMarkableResourceRecoveryModule.periodicWorkFirstPass();
    XAResourceOrphanFilter.Vote vote = new JTATransactionLogXAResourceOrphanFilter().checkXid(preparedXid);
    assertTrue(vote == XAResourceOrphanFilter.Vote.LEAVE_ALONE);
    manager.scan();
    manager.scan();
    assertTrue(wasCommitted);
}
Also used : Enumeration(java.util.Enumeration) JdbcDataSource(org.h2.jdbcx.JdbcDataSource) Connection(java.sql.Connection) JTATransactionLogXAResourceOrphanFilter(com.arjuna.ats.internal.jta.recovery.arjunacore.JTATransactionLogXAResourceOrphanFilter) XAResourceRecoveryHelper(com.arjuna.ats.jta.recovery.XAResourceRecoveryHelper) ExecuteException(org.jboss.byteman.rule.exception.ExecuteException) XAException(javax.transaction.xa.XAException) InitialContext(javax.naming.InitialContext) XAResource(javax.transaction.xa.XAResource) ExecuteException(org.jboss.byteman.rule.exception.ExecuteException) CommitMarkableResourceRecordRecoveryModule(com.arjuna.ats.internal.jta.recovery.arjunacore.CommitMarkableResourceRecordRecoveryModule) RecoveryModule(com.arjuna.ats.arjuna.recovery.RecoveryModule) XARecoveryModule(com.arjuna.ats.internal.jta.recovery.arjunacore.XARecoveryModule) CommitMarkableResourceRecordRecoveryModule(com.arjuna.ats.internal.jta.recovery.arjunacore.CommitMarkableResourceRecordRecoveryModule) Vector(java.util.Vector) XAResourceOrphanFilter(com.arjuna.ats.jta.recovery.XAResourceOrphanFilter) JTATransactionLogXAResourceOrphanFilter(com.arjuna.ats.internal.jta.recovery.arjunacore.JTATransactionLogXAResourceOrphanFilter) XARecoveryModule(com.arjuna.ats.internal.jta.recovery.arjunacore.XARecoveryModule) Test(org.junit.Test) BMScript(org.jboss.byteman.contrib.bmunit.BMScript)

Example 7 with ExecuteException

use of org.jboss.byteman.rule.exception.ExecuteException in project narayana by jbosstm.

the class SimpleIsolatedServers method testSimultaneousRecover.

/**
 * Ensure that two servers can start up and call recover on the same server
 *
 * The JCA XATerminator call wont allow intermediary calls to
 * XATerminator::recover between TMSTARTSCAN and TMENDSCAN. This is fine for
 * distributed JTA.
 *
 * @throws XAException
 * @throws IOException
 * @throws DummyRemoteException
 */
@Test
@BMScript("leave-subordinate-orphan")
public void testSimultaneousRecover() throws Exception {
    System.out.println("testSimultaneousRecover");
    assertTrue("" + completionCounter.getCommitCount("2000"), completionCounter.getCommitCount("2000") == 0);
    assertTrue("" + completionCounter.getRollbackCount("2000"), completionCounter.getRollbackCount("2000") == 0);
    assertTrue("" + completionCounter.getCommitCount("1000"), completionCounter.getCommitCount("1000") == 0);
    assertTrue("" + completionCounter.getRollbackCount("1000"), completionCounter.getRollbackCount("1000") == 0);
    final CompletionCountLock phase2CommitAborted = new CompletionCountLock();
    synchronized (phase2CommitAborted) {
        {
            Thread thread = new Thread(new Runnable() {

                public void run() {
                    int startingTimeout = 0;
                    try {
                        LocalServer originalServer = getLocalServer("1000");
                        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
                        Thread.currentThread().setContextClassLoader(originalServer.getClassLoader());
                        TransactionManager transactionManager = originalServer.getTransactionManager();
                        transactionManager.setTransactionTimeout(startingTimeout);
                        transactionManager.begin();
                        Transaction originalTransaction = transactionManager.getTransaction();
                        int remainingTimeout = (int) (originalServer.getTimeLeftBeforeTransactionTimeout() / 1000);
                        Xid currentXid = originalServer.getCurrentXid();
                        transactionManager.suspend();
                        DataReturnedFromRemoteServer performTransactionalWork = performTransactionalWork(new LinkedList<String>(Arrays.asList(new String[] { "2000" })), remainingTimeout, currentXid, 2, false, false);
                        transactionManager.resume(originalTransaction);
                        XAResource proxyXAResource = originalServer.generateProxyXAResource("2000", performTransactionalWork.getProxyRequired());
                        originalTransaction.enlistResource(proxyXAResource);
                        transactionManager.commit();
                        Thread.currentThread().setContextClassLoader(classLoader);
                        synchronized (phase2CommitAborted) {
                            phase2CommitAborted.notify();
                        }
                    } catch (ExecuteException e) {
                        System.err.println("Should be a thread death but cest la vie");
                        synchronized (phase2CommitAborted) {
                            phase2CommitAborted.incrementCount();
                            phase2CommitAborted.notify();
                        }
                    } catch (LinkageError t) {
                        System.err.println("Should be a thread death but cest la vie");
                        synchronized (phase2CommitAborted) {
                            phase2CommitAborted.incrementCount();
                            phase2CommitAborted.notify();
                        }
                    } catch (Throwable t) {
                        System.err.println("Should be a thread death but cest la vie");
                        synchronized (phase2CommitAborted) {
                            phase2CommitAborted.incrementCount();
                            phase2CommitAborted.notify();
                        }
                    }
                }
            }, "Orphan-creator");
            thread.start();
        }
        {
            Thread thread = new Thread(new Runnable() {

                public void run() {
                    int startingTimeout = 0;
                    try {
                        LocalServer originalServer = getLocalServer("2000");
                        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
                        Thread.currentThread().setContextClassLoader(originalServer.getClassLoader());
                        TransactionManager transactionManager = originalServer.getTransactionManager();
                        transactionManager.setTransactionTimeout(startingTimeout);
                        transactionManager.begin();
                        Transaction originalTransaction = transactionManager.getTransaction();
                        int remainingTimeout = (int) (originalServer.getTimeLeftBeforeTransactionTimeout() / 1000);
                        Xid currentXid = originalServer.getCurrentXid();
                        transactionManager.suspend();
                        DataReturnedFromRemoteServer performTransactionalWork = performTransactionalWork(new LinkedList<String>(Arrays.asList(new String[] { "1000" })), remainingTimeout, currentXid, 2, false, false);
                        transactionManager.resume(originalTransaction);
                        XAResource proxyXAResource = originalServer.generateProxyXAResource("1000", performTransactionalWork.getProxyRequired());
                        originalTransaction.enlistResource(proxyXAResource);
                        transactionManager.commit();
                        Thread.currentThread().setContextClassLoader(classLoader);
                        synchronized (phase2CommitAborted) {
                            phase2CommitAborted.notify();
                        }
                    } catch (ExecuteException e) {
                        System.err.println("Should be a thread death but cest la vie");
                        synchronized (phase2CommitAborted) {
                            phase2CommitAborted.incrementCount();
                            phase2CommitAborted.notify();
                        }
                    } catch (LinkageError t) {
                        System.err.println("Should be a thread death but cest la vie");
                        synchronized (phase2CommitAborted) {
                            phase2CommitAborted.incrementCount();
                            phase2CommitAborted.notify();
                        }
                    } catch (Throwable t) {
                        System.err.println("Should be a thread death but cest la vie");
                        synchronized (phase2CommitAborted) {
                            phase2CommitAborted.incrementCount();
                            phase2CommitAborted.notify();
                        }
                    }
                }
            }, "Orphan-creator");
            thread.start();
        }
        int waitedCount = 0;
        while (waitedCount < 2) {
            phase2CommitAborted.wait(50000);
            waitedCount++;
            if (waitedCount == 2 && phase2CommitAborted.getCount() < 2) {
                fail("Servers were not aborted");
            }
        }
    }
    reboot("1000");
    reboot("2000");
    reboot("3000");
    final CompletionCountLock lock = new CompletionCountLock();
    {
        new Thread(new Runnable() {

            public void run() {
                getLocalServer("2000").doRecoveryManagerScan(true);
                lock.incrementCount();
            }
        }, "RecMan2000").start();
    }
    {
        new Thread(new Runnable() {

            public void run() {
                getLocalServer("1000").doRecoveryManagerScan(true);
                lock.incrementCount();
            }
        }, "RecMan1000").start();
    }
    synchronized (lock) {
        while (lock.getCount() < 2) {
            lock.wait(300000);
        }
        if (lock.getCount() < 2) {
            fail("Did not get notification for both recovery runs, deadlock in recovery manager scan detected");
            ProcessBuilder processBuilder = new ProcessBuilder("/bin/sh", "-c", "kill -3 $PPID");
            processBuilder.redirectErrorStream(true);
            Process process = processBuilder.start();
            InputStream inputStream = process.getInputStream();
            final byte[] bytes = new byte[4096];
            int bytesRead = inputStream.read(bytes);
            while (bytesRead > -1) {
                System.out.write(bytes, 0, bytesRead);
                bytesRead = inputStream.read(bytes);
            }
        }
    }
    assertTrue("" + completionCounter.getCommitCount("1000"), completionCounter.getCommitCount("1000") == 0);
    // JBTM-1260 simultaneous recover can cause spurious Xid rollback of normally completed Xid, should not be an issue
    // JBTM-1345 simulatenous recover can cause spurious Xid rollback of completed resources, should not be a data integrity issue
    assertTrue("" + completionCounter.getRollbackCount("1000"), Arrays.asList(new Integer[] { 3, 4, 5 }).contains(completionCounter.getRollbackCount("1000")));
    assertTrue("" + completionCounter.getCommitCount("2000"), completionCounter.getCommitCount("2000") == 0);
    assertTrue("" + completionCounter.getRollbackCount("2000"), Arrays.asList(new Integer[] { 3, 4, 5 }).contains(completionCounter.getRollbackCount("2000")));
}
Also used : LocalServer(com.arjuna.ats.jta.distributed.server.LocalServer) InputStream(java.io.InputStream) Xid(javax.transaction.xa.Xid) XAResource(javax.transaction.xa.XAResource) Transaction(javax.transaction.Transaction) TransactionManager(javax.transaction.TransactionManager) IsolatableServersClassLoader(com.arjuna.ats.jta.distributed.server.IsolatableServersClassLoader) ExecuteException(org.jboss.byteman.rule.exception.ExecuteException) Test(org.junit.Test) BMScript(org.jboss.byteman.contrib.bmunit.BMScript)

Aggregations

XAResource (javax.transaction.xa.XAResource)7 ExecuteException (org.jboss.byteman.rule.exception.ExecuteException)7 RecoveryModule (com.arjuna.ats.arjuna.recovery.RecoveryModule)6 CommitMarkableResourceRecordRecoveryModule (com.arjuna.ats.internal.jta.recovery.arjunacore.CommitMarkableResourceRecordRecoveryModule)6 XARecoveryModule (com.arjuna.ats.internal.jta.recovery.arjunacore.XARecoveryModule)6 XAResourceRecoveryHelper (com.arjuna.ats.jta.recovery.XAResourceRecoveryHelper)6 Connection (java.sql.Connection)6 Enumeration (java.util.Enumeration)6 Vector (java.util.Vector)6 InitialContext (javax.naming.InitialContext)5 Xid (javax.transaction.xa.Xid)5 JdbcDataSource (org.h2.jdbcx.JdbcDataSource)4 BMScript (org.jboss.byteman.contrib.bmunit.BMScript)4 Test (org.junit.Test)4 DataSource (javax.sql.DataSource)2 Uid (com.arjuna.ats.arjuna.common.Uid)1 ObjectStoreException (com.arjuna.ats.arjuna.exceptions.ObjectStoreException)1 RecoveryManagerImple (com.arjuna.ats.internal.arjuna.recovery.RecoveryManagerImple)1 JTATransactionLogXAResourceOrphanFilter (com.arjuna.ats.internal.jta.recovery.arjunacore.JTATransactionLogXAResourceOrphanFilter)1 TransactionImple (com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple)1