/** @throws Exception */ public void testDoCommit() throws Exception { Xid xid = new XidImpl(); xares_.start(xid, XAResource.TMNOFLAGS); xares_.end(xid, XAResource.TMSUCCESS); xares_.commit(xid, true); assertEquals("1", true, con_.getAutoCommit()); }
private boolean runXaResourceCommitTx() throws HeuristicMixedException { Collection<XAResource> resources = getEnlistedResources(); for (XAResource res : resources) { try { res.commit(xid, false); // todo we only support one phase commit for now, change this!!! } catch (XAException e) { log.warn("exception while committing", e); throw new HeuristicMixedException(e.getMessage()); } } return true; }
/** commit the resource */ public void commit(Xid xid, boolean onePhase) throws XAException { boolean logFiner = log.isLoggable(Level.FINER); try { int endFlags = _endFlags; _endFlags = -1; if (endFlags != -1 && _isXATransaction) { boolean isValid = false; try { endResource(xid, endFlags); isValid = true; } finally { if (!isValid) _xaResource.rollback(xid); } } if (_isXATransaction) { if (logFiner) { log.finer("commit-XA" + (onePhase ? "-1p: " : ": ") + xid + " " + _xaResource); } try { _xaResource.commit(xid, onePhase); } catch (XAException e) { if (logFiner) log.finer("commit-XA failed: " + _xaResource + " " + e); throw e; } } else if (_localTransaction != null) { if (logFiner) log.finer("commit-local: " + _localTransaction); try { _localTransaction.commit(); } catch (ResourceException e) { if (logFiner) log.finer("commit failed: " + _localTransaction + " " + e); throw new XAExceptionWrapper(e); } finally { _isLocalTransaction = false; } } else { if (logFiner) log.finer("commit for resource with no XA support: " + this); } } finally { if (_xaResource != null) _isXATransaction = true; clearXid(); } }
protected int doCommit(Xid xid, int cPhase) throws XAException { int returnVal = -1; synchronized (physicalConn) { synchronized (this) { int command = cPhase != 1 ? 2 : 4; returnVal = doTransaction(xid, 1, command); if (cPhase == 1 && (returnVal == 2 || returnVal == 4)) { returnVal = 0; } else if (cPhase != 1 && returnVal == 5) { returnVal = 0; } else if (returnVal == 8) { throw new XAException(106); } if (returnVal == 24756) { returnVal = kputxrec(xid, 1, timeout + 120); } else if (returnVal == 24780) { OracleXADataSource oxds = null; XAConnection pc = null; try { oxds = new OracleXADataSource(); oxds.setURL(physicalConn.url); oxds.setUser(physicalConn.user); physicalConn.getPasswordInternal(this); oxds.setPassword(password); pc = oxds.getXAConnection(); XAResource oxar = pc.getXAResource(); oxar.commit(xid, cPhase == 1); returnVal = 0; } catch (SQLException e) { throw new XAException(-6); } finally { try { if (pc != null) { pc.close(); } if (oxds != null) { oxds.close(); } } catch (Exception ee) { } } } } } return returnVal; }
@Override public void commit(Xid xid, boolean b) throws XAException { // Commit only if not read only. if (prepareResult != XAResource.XA_RDONLY) xaResource.commit(xid, b); else log.tracef("Not committing {0} due to readonly.", xid); }
private void checkXAHoldability() { System.out.println("START XA HOLDABILITY TEST"); try { EmbeddedXADataSource dscsx = new EmbeddedXADataSource(); dscsx.setDatabaseName("wombat"); XAConnection xac = dscsx.getXAConnection("fred", "wilma"); XAResource xr = xac.getXAResource(); Xid xid = getXid(25, (byte) 21, (byte) 01); Connection conn1 = xac.getConnection(); System.out.println( "By default, autocommit is " + conn1.getAutoCommit() + " for a connection"); System.out.println("Default holdability for a connection is HOLD_CURSORS_OVER_COMMIT"); System.out.println( "CONNECTION(not in xa transaction yet) HOLDABILITY " + (conn1.getHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); // start a global transaction and default holdability and autocommit will be switched to match // Derby XA restrictions xr.start(xid, XAResource.TMNOFLAGS); System.out.println( "Notice that autocommit now is " + conn1.getAutoCommit() + " for connection because it is part of the global transaction"); System.out.println( "Notice that connection's holdability at this point is CLOSE_CURSORS_AT_COMMIT because it is part of the global transaction"); System.out.println( "CONNECTION(in xa transaction) HOLDABILITY " + (conn1.getHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); xr.end(xid, XAResource.TMSUCCESS); conn1.commit(); conn1.close(); xid = getXid(27, (byte) 21, (byte) 01); xr.start(xid, XAResource.TMNOFLAGS); conn1 = xac.getConnection(); System.out.println( "CONNECTION(in xa transaction) HOLDABILITY " + (conn1.getHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); System.out.println( "Autocommit on Connection inside global transaction has been set correctly to " + conn1.getAutoCommit()); xr.end(xid, XAResource.TMSUCCESS); conn1.rollback(); Connection conn = xac.getConnection(); conn.setAutoCommit(false); conn.setHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT); System.out.println( "CONNECTION(non-xa) HOLDABILITY " + (conn.getHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); Statement s = conn.createStatement(); System.out.println( "STATEMENT HOLDABILITY " + (s.getResultSetHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); s.executeUpdate("create table hold_30 (id int not null primary key, b char(30))"); s.executeUpdate("insert into hold_30 values (1,'init2'), (2, 'init3'), (3,'init3')"); s.executeUpdate("insert into hold_30 values (4,'init4'), (5, 'init5'), (6,'init6')"); s.executeUpdate("insert into hold_30 values (7,'init7'), (8, 'init8'), (9,'init9')"); System.out.println( "STATEMENT HOLDABILITY " + (s.getResultSetHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); Statement sh = conn.createStatement( ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); PreparedStatement psh = conn.prepareStatement( "select id from hold_30 for update", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); CallableStatement csh = conn.prepareCall( "select id from hold_30 for update", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); System.out.println( "STATEMENT HOLDABILITY " + (sh.getResultSetHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); System.out.println( "PREPARED STATEMENT HOLDABILITY " + (psh.getResultSetHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); System.out.println( "CALLABLE STATEMENT HOLDABILITY " + (csh.getResultSetHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); ResultSet rsh = sh.executeQuery("select id from hold_30 for update"); rsh.next(); System.out.println("H@1 id " + rsh.getInt(1)); rsh.next(); System.out.println("H@2 id " + rsh.getInt(1)); conn.commit(); rsh.next(); System.out.println("H@3 id " + rsh.getInt(1)); conn.commit(); xid = getXid(23, (byte) 21, (byte) 01); xr.start(xid, XAResource.TMNOFLAGS); Statement stmtInsideGlobalTransaction = conn.createStatement(); PreparedStatement prepstmtInsideGlobalTransaction = conn.prepareStatement("select id from hold_30"); CallableStatement callablestmtInsideGlobalTransaction = conn.prepareCall("select id from hold_30"); System.out.println( "CONNECTION(xa) HOLDABILITY " + (conn.getHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); System.out.println( "STATEMENT(this one was created with holdability false, outside the global transaction. Check it's holdability inside global transaction) HOLDABILITY " + (s.getResultSetHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); System.out.println( "STATEMENT(this one was created with holdability true, outside the global transaction. Check it's holdability inside global transaction) HOLDABILITY " + (sh.getResultSetHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); System.out.println( "STATEMENT(this one was created with default holdability inside this global transaction. Check it's holdability) HOLDABILITY " + (stmtInsideGlobalTransaction.getResultSetHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); System.out.println( "PREPAREDSTATEMENT(this one was created with default holdability inside this global transaction. Check it's holdability) HOLDABILITY " + (prepstmtInsideGlobalTransaction.getResultSetHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); System.out.println( "CALLABLESTATEMENT(this one was created with default holdability inside this global transaction. Check it's holdability) HOLDABILITY " + (callablestmtInsideGlobalTransaction.getResultSetHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); ResultSet rsx = s.executeQuery("select id from hold_30 for update"); rsx.next(); System.out.println("X@1 id " + rsx.getInt(1)); rsx.next(); System.out.println("X@2 id " + rsx.getInt(1)); xr.end(xid, XAResource.TMSUCCESS); // result set should not be useable, since it is part of a detached // XAConnection try { rsx.next(); System.out.println("FAIL - rsx's connection not active id " + rsx.getInt(1)); } catch (SQLException sqle) { System.out.println("Expected SQLException " + sqle.getMessage()); } // result set should not be useable, it should have been closed by the xa start. try { rsh.next(); System.out.println("FAIL - rsh's should be closed " + rsx.getInt(1)); } catch (SQLException sqle) { System.out.println("Expected SQLException " + sqle.getMessage()); } System.out.println("resume XA transaction and keep using rs"); xr.start(xid, XAResource.TMJOIN); Statement stmtAfterGlobalTransactionResume = conn.createStatement(); PreparedStatement prepstmtAfterGlobalTransactionResume = conn.prepareStatement("select id from hold_30"); CallableStatement callablestmtAfterGlobalTransactionResume = conn.prepareCall("select id from hold_30"); System.out.println("Check holdability of various jdbc objects after resuming XA transaction"); System.out.println( "CONNECTION(xa) HOLDABILITY " + (conn.getHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); System.out.println( "STATEMENT(this one was created with holdability false, outside the global transaction. Check it's holdability inside global transaction) HOLDABILITY " + (s.getResultSetHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); System.out.println( "STATEMENT(this one was created with holdability true, outside the global transaction. Check it's holdability inside global transaction) HOLDABILITY " + (sh.getResultSetHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); System.out.println( "STATEMENT(this one was created with default holdability inside the global transaction when it was first started. Check it's holdability) HOLDABILITY " + (stmtInsideGlobalTransaction.getResultSetHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); System.out.println( "PREPAREDSTATEMENT(this one was created with default holdability inside the global transaction when it was first started. Check it's holdability) HOLDABILITY " + (prepstmtInsideGlobalTransaction.getResultSetHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); System.out.println( "CALLABLESTATEMENT(this one was created with default holdability inside the global transaction when it was first started. Check it's holdability) HOLDABILITY " + (callablestmtInsideGlobalTransaction.getResultSetHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); System.out.println( "STATEMENT(this one was created with default holdability after the global transaction was resumed. Check it's holdability) HOLDABILITY " + (stmtAfterGlobalTransactionResume.getResultSetHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); System.out.println( "PREPAREDSTATEMENT(this one was created with default holdability after the global transaction was resumed. Check it's holdability) HOLDABILITY " + (prepstmtAfterGlobalTransactionResume.getResultSetHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); System.out.println( "CALLABLESTATEMENT(this one was created with default holdability after the global transaction was resumed. Check it's holdability) HOLDABILITY " + (callablestmtAfterGlobalTransactionResume.getResultSetHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); rsx.next(); System.out.println("X@3 id " + rsx.getInt(1)); xr.end(xid, XAResource.TMSUCCESS); if (xr.prepare(xid) != XAResource.XA_RDONLY) xr.commit(xid, false); // try again once the xa transaction has been committed. try { rsx.next(); System.out.println("FAIL - rsx's connection not active id (B)" + rsx.getInt(1)); } catch (SQLException sqle) { System.out.println("Expected SQLException " + sqle.getMessage()); } try { rsh.next(); System.out.println("FAIL - rsh's should be closed (B) " + rsx.getInt(1)); } catch (SQLException sqle) { System.out.println("Expected SQLException " + sqle.getMessage()); } System.out.println("Set connection to hold "); conn.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT); System.out.println( "CONNECTION(held) HOLDABILITY " + (conn.getHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); xid = getXid(24, (byte) 21, (byte) 01); xr.start(xid, XAResource.TMNOFLAGS); System.out.println( "CONNECTION(xa) HOLDABILITY " + (conn.getHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); try { conn.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT); System.out.println("FAIL allowed to set hold mode in xa transaction"); } catch (SQLException sqle) { System.out.println("Expected SQLException(setHoldability) " + sqle.getMessage()); } // try to create a statement with held attributes try { Statement shxa = conn.createStatement( ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); System.out.println( "FAIL opened statement with hold cursor attribute in global transaction"); } catch (SQLException sqle) { System.out.println("Expected SQLException (Statement hold) " + sqle.getMessage()); } try { Statement shxa = conn.prepareStatement( "select id from hold_30", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); System.out.println( "FAIL opened statement with hold cursor attribute in global transaction"); } catch (SQLException sqle) { System.out.println("Expected SQLException (PreparedStatement hold) " + sqle.getMessage()); } try { Statement shxa = conn.prepareCall( "CALL XXX.TTT()", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); System.out.println( "FAIL opened statement with hold cursor attribute in global transaction"); } catch (SQLException sqle) { System.out.println("Expected SQLException (CallableStatement hold) " + sqle.getMessage()); } // check we cannot use a holdable statement set up in local mode. System.out.println( "STATEMENT HOLDABILITY " + (sh.getResultSetHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); try { sh.executeQuery("select id from hold_30"); System.out.println("FAIL used held statement in global transaction"); } catch (SQLException sqle) { System.out.println("Expected SQLException (local Statement hold) " + sqle.getMessage()); } try { sh.execute("select id from hold_30"); System.out.println("FAIL used held statement in global transaction"); } catch (SQLException sqle) { System.out.println("Expected SQLException (local Statement hold) " + sqle.getMessage()); } System.out.println( "PREPARED STATEMENT HOLDABILITY " + (psh.getResultSetHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); try { psh.executeQuery(); System.out.println("FAIL used held prepared statement in global transaction"); } catch (SQLException sqle) { System.out.println( "Expected SQLException (local PreparedStatement hold) " + sqle.getMessage()); } try { psh.execute(); System.out.println("FAIL used held prepared statement in global transaction"); } catch (SQLException sqle) { System.out.println( "Expected SQLException (local PreparedStatement hold) " + sqle.getMessage()); } System.out.println( "CALLABLE STATEMENT HOLDABILITY " + (csh.getResultSetHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); try { csh.executeQuery(); System.out.println("FAIL used held callable statement in global transaction"); } catch (SQLException sqle) { System.out.println( "Expected SQLException (local CallableStatement hold) " + sqle.getMessage()); } try { csh.execute(); System.out.println("FAIL used held callable statement in global transaction"); } catch (SQLException sqle) { System.out.println( "Expected SQLException (local CallableStatement hold) " + sqle.getMessage()); } // but an update works sh.executeUpdate("insert into hold_30 values(10, 'init10')"); xr.end(xid, XAResource.TMSUCCESS); System.out.println( "CONNECTION(held) HOLDABILITY " + (conn.getHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT)); conn.close(); System.out.println("PASS XA HOLDABILITY TEST"); } catch (XAException xae) { System.out.println("XAException error code " + xae.errorCode); xae.printStackTrace(System.out); Throwable t = xae.getCause(); if (t instanceof SQLException) JDBCDisplayUtil.ShowSQLException(System.out, (SQLException) t); } catch (SQLException sqle) { JDBCDisplayUtil.ShowSQLException(System.out, sqle); } catch (Throwable t) { t.printStackTrace(System.out); } System.out.flush(); }
/** * Tests that simple distributed transaction processing works as expected. * * @throws Exception if the test fails. */ public void testCoordination() throws Exception { if (!versionMeetsMinimum(5, 0)) { return; } createTable("testCoordination", "(field1 int) ENGINE=InnoDB"); Connection conn1 = null; Connection conn2 = null; XAConnection xaConn1 = null; XAConnection xaConn2 = null; try { xaConn1 = getXAConnection(); XAResource xaRes1 = xaConn1.getXAResource(); conn1 = xaConn1.getConnection(); xaConn2 = getXAConnection(); XAResource xaRes2 = xaConn2.getXAResource(); conn2 = xaConn2.getConnection(); Xid xid1 = createXid(); Xid xid2 = createXid(xid1); xaRes1.start(xid1, XAResource.TMNOFLAGS); xaRes2.start(xid2, XAResource.TMNOFLAGS); conn1.createStatement().executeUpdate("INSERT INTO testCoordination VALUES (1)"); conn2.createStatement().executeUpdate("INSERT INTO testCoordination VALUES (2)"); xaRes1.end(xid1, XAResource.TMSUCCESS); xaRes2.end(xid2, XAResource.TMSUCCESS); xaRes1.prepare(xid1); xaRes2.prepare(xid2); xaRes1.commit(xid1, false); xaRes2.commit(xid2, false); this.rs = this.stmt.executeQuery("SELECT field1 FROM testCoordination ORDER BY field1"); assertTrue(this.rs.next()); assertEquals(1, this.rs.getInt(1)); assertTrue(this.rs.next()); assertEquals(2, this.rs.getInt(1)); this.stmt.executeUpdate("TRUNCATE TABLE testCoordination"); // // Now test rollback // xid1 = createXid(); xid2 = createXid(xid1); xaRes1.start(xid1, XAResource.TMNOFLAGS); xaRes2.start(xid2, XAResource.TMNOFLAGS); conn1.createStatement().executeUpdate("INSERT INTO testCoordination VALUES (1)"); // ensure visibility assertEquals( "1", getSingleIndexedValueWithQuery( conn1, 1, "SELECT field1 FROM testCoordination WHERE field1=1") .toString()); conn2.createStatement().executeUpdate("INSERT INTO testCoordination VALUES (2)"); // ensure visibility assertEquals( "2", getSingleIndexedValueWithQuery( conn2, 1, "SELECT field1 FROM testCoordination WHERE field1=2") .toString()); xaRes1.end(xid1, XAResource.TMSUCCESS); xaRes2.end(xid2, XAResource.TMSUCCESS); xaRes1.prepare(xid1); xaRes2.prepare(xid2); xaRes1.rollback(xid1); xaRes2.rollback(xid2); this.rs = this.stmt.executeQuery("SELECT field1 FROM testCoordination ORDER BY field1"); assertTrue(!this.rs.next()); } finally { if (conn1 != null) { conn1.close(); } if (conn2 != null) { conn2.close(); } if (xaConn1 != null) { xaConn1.close(); } if (xaConn2 != null) { xaConn2.close(); } } }
public void testSuspendableTx() throws Exception { if (!versionMeetsMinimum(5, 0)) { return; } Connection conn1 = null; MysqlXADataSource suspXaDs = new MysqlXADataSource(); suspXaDs.setUrl(BaseTestCase.dbUrl); suspXaDs.setPinGlobalTxToPhysicalConnection(true); suspXaDs.setRollbackOnPooledClose(true); XAConnection xaConn1 = null; Xid xid = createXid(); try { /* * -- works using RESUME * xa start 0x123,0x456; * select * from foo; * xa end 0x123,0x456; * xa start 0x123,0x456 resume; * select * from foo; * xa end 0x123,0x456; * xa commit 0x123,0x456 one phase; */ xaConn1 = suspXaDs.getXAConnection(); XAResource xaRes1 = xaConn1.getXAResource(); conn1 = xaConn1.getConnection(); xaRes1.start(xid, XAResource.TMNOFLAGS); conn1.createStatement().executeQuery("SELECT 1"); xaRes1.end(xid, XAResource.TMSUCCESS); xaRes1.start(xid, XAResource.TMRESUME); conn1.createStatement().executeQuery("SELECT 1"); xaRes1.end(xid, XAResource.TMSUCCESS); xaRes1.commit(xid, true); xaConn1.close(); /* * * -- fails using JOIN * xa start 0x123,0x456; * select * from foo; * xa end 0x123,0x456; * xa start 0x123,0x456 join; * select * from foo; * xa end 0x123,0x456; * xa commit 0x123,0x456 one phase; */ xaConn1 = suspXaDs.getXAConnection(); xaRes1 = xaConn1.getXAResource(); conn1 = xaConn1.getConnection(); xaRes1.start(xid, XAResource.TMNOFLAGS); conn1.createStatement().executeQuery("SELECT 1"); xaRes1.end(xid, XAResource.TMSUCCESS); xaRes1.start(xid, XAResource.TMJOIN); conn1.createStatement().executeQuery("SELECT 1"); xaRes1.end(xid, XAResource.TMSUCCESS); xaRes1.commit(xid, true); } finally { if (xaConn1 != null) { xaConn1.close(); } } }
@Override public void commit(Xid xid, boolean onePhase) throws XAException { resource.commit(xid, onePhase); }
@Override public boolean runExample() throws Exception { XAConnection connection = null; InitialContext initialContext = null; try { // Step 1. Create an initial context to perform the JNDI lookup. initialContext = getContext(0); // Step 2. Lookup on the queue Queue queue = (Queue) initialContext.lookup("/queue/exampleQueue"); // Step 3. Perform a lookup on the XA Connection Factory XAConnectionFactory cf = (XAConnectionFactory) initialContext.lookup("/XAConnectionFactory"); // Step 4.Create a JMS XAConnection connection = cf.createXAConnection(); // Step 5. Start the connection connection.start(); // Step 6. Create a JMS XASession XASession xaSession = connection.createXASession(); // Step 7. Create a normal session Session normalSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // Step 8. Create a normal Message Consumer MessageConsumer normalConsumer = normalSession.createConsumer(queue); normalConsumer.setMessageListener(new SimpleMessageListener()); // Step 9. Get the JMS Session Session session = xaSession.getSession(); // Step 10. Create a message producer MessageProducer producer = session.createProducer(queue); // Step 11. Create two Text Messages TextMessage helloMessage = session.createTextMessage("hello"); TextMessage worldMessage = session.createTextMessage("world"); // Step 12. create a transaction Xid xid1 = new DummyXid( "xa-example1".getBytes(CharsetUtil.UTF_8), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes()); // Step 13. Get the JMS XAResource XAResource xaRes = xaSession.getXAResource(); // Step 14. Begin the Transaction work xaRes.start(xid1, XAResource.TMNOFLAGS); // Step 15. do work, sending two messages. producer.send(helloMessage); producer.send(worldMessage); Thread.sleep(2000); // Step 16. Check the result, it should receive none! checkNoMessageReceived(); // Step 17. Stop the work xaRes.end(xid1, XAResource.TMSUCCESS); // Step 18. Prepare xaRes.prepare(xid1); // Step 19. Roll back the transaction xaRes.rollback(xid1); // Step 20. No messages should be received! checkNoMessageReceived(); // Step 21. Create another transaction Xid xid2 = new DummyXid( "xa-example2".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes()); // Step 22. Start the transaction xaRes.start(xid2, XAResource.TMNOFLAGS); // Step 23. Re-send those messages producer.send(helloMessage); producer.send(worldMessage); // Step 24. Stop the work xaRes.end(xid2, XAResource.TMSUCCESS); // Step 25. Prepare xaRes.prepare(xid2); // Step 26. No messages should be received at this moment checkNoMessageReceived(); // Step 27. Commit! xaRes.commit(xid2, false); Thread.sleep(2000); // Step 28. Check the result, all message received checkAllMessageReceived(); return result; } finally { // Step 29. Be sure to close our JMS resources! if (initialContext != null) { initialContext.close(); } if (connection != null) { connection.close(); } } }
private void commitTx() throws XAException { xaResource.end(dummyXid, XAResource.TMSUCCESS); xaResource.commit(dummyXid, true); // xaCon.clearAllTransactions(); }