[jboss-cvs] JBossAS SVN: r83758 - branches/Branch_5_x/connector/src/main/org/jboss/resource/adapter/jms/inflow.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Mon Feb 2 00:08:25 EST 2009
Author: jhowell at redhat.com
Date: 2009-02-02 00:08:25 -0500 (Mon, 02 Feb 2009)
New Revision: 83758
Modified:
branches/Branch_5_x/connector/src/main/org/jboss/resource/adapter/jms/inflow/JmsServerSession.java
Log:
[JBAS-6343] - Fixed introduced regression. Refactored code and made it easier to write unit tests for the transactionDemarcation inner classes.
Modified: branches/Branch_5_x/connector/src/main/org/jboss/resource/adapter/jms/inflow/JmsServerSession.java
===================================================================
--- branches/Branch_5_x/connector/src/main/org/jboss/resource/adapter/jms/inflow/JmsServerSession.java 2009-02-02 04:53:26 UTC (rev 83757)
+++ branches/Branch_5_x/connector/src/main/org/jboss/resource/adapter/jms/inflow/JmsServerSession.java 2009-02-02 05:08:25 UTC (rev 83758)
@@ -286,11 +286,21 @@
final JmsActivation activation = pool.getActivation();
try
{
- if (activation.isDeliveryTransacted() && xaSession != null)
+ //If we have a transacted delivery
+ if (activation.isDeliveryTransacted() )
{
- current = new XATransactionDemarcationStrategy();
- }
- else
+ //if we have an XASession
+ if(xaSession != null)
+ {
+ current = new XATransactionDemarcationStrategy();
+ }
+ else //if we don't have an XASession, simulate it with a transacted session
+ {
+ current = new SimulatedXATransactionDemarcationStrategy();
+ }
+
+ }
+ else
{
current = new LocalDemarcationStrategy();
}
@@ -313,277 +323,367 @@
}
/**
+ * This class simulates xa using a transacted session for connection factories that don't have an xa interface. This is true with
+ * default ibmmq adapter. It is not XA, but still needs to be able to have transactions. So for these connection factories we
+ * use transacted sessions to commit and rollback, while monitoring the transaction.
+ *
* JBAS-6343 - This class is exactly like the XADemarcationStrategy, but it uses a transacted session under the covers.
* Unfortuneately we have to start a transaction the for local, because we need to be able to get a handle to any failed
* transactions.
* @author jhowell
*
*/
- private class LocalDemarcationStrategy implements TransactionDemarcationStrategy
- {
+ private class SimulatedXATransactionDemarcationStrategy implements
+ TransactionDemarcationStrategy
+ {
- boolean trace = log.isTraceEnabled();
+ boolean trace = log.isTraceEnabled();
- Transaction trans = null;
+ Transaction trans = null;
- TransactionManager tm = pool.getActivation().getTransactionManager();;
+ TransactionManager tm = pool.getActivation().getTransactionManager();;
- public LocalDemarcationStrategy() throws Throwable
- {
+ public SimulatedXATransactionDemarcationStrategy() throws Throwable
+ {
+ final int timeout = pool.getActivation().getActivationSpec()
+ .getTransactionTimeout();
- final int timeout = pool.getActivation().getActivationSpec().getTransactionTimeout();
+ if (timeout > 0)
+ {
+ log.trace("Setting transactionTimeout for JMSSessionPool to "
+ + timeout);
+ tm.setTransactionTimeout(timeout);
- if (timeout > 0)
- {
- log.trace("Setting transactionTimeout for JMSSessionPool to " + timeout);
- tm.setTransactionTimeout(timeout);
- }
- //we need to begin a tx so that we can get a handle to the tx in end. In end we will roll back the session.
- tm.begin();
- trans=tm.getTransaction();
- }
+ }
- public void error()
- {
- final JmsActivationSpec spec = pool.getActivation().getActivationSpec();
+ tm.begin();
- if (spec.isSessionTransacted())
- {
- if (session != null)
+ try
+ {
+ trans = tm.getTransaction();
- try
- {
-
- /*
- * Looks strange, but this basically means
- *
- * JBAS-6343 - If the underlying connection was non-XA and the transaction attribute is REQUIRED
- * we rollback. Also, if the underlying connection was non-XA and the transaction
- * attribute is NOT_SUPPORT and the non standard redelivery behavior is enabled
- * we rollback to force redelivery.
- *
- */
- if (pool.getActivation().isDeliveryTransacted() || spec.getRedeliverUnspecified())
- {
- log.debug(JmsServerSession.this +"Rolling transacted session back due to an error");
- session.rollback();
- }
+ if (trace)
+ log.trace(JmsServerSession.this + " using tx=" + trans);
+
+ } catch (Throwable t)
+ {
+ try
+ {
+ tm.rollback();
+ } catch (Throwable ignored)
+ {
+ log.trace(JmsServerSession.this+ " ignored error rolling back after failing to get transaction", ignored);
+ }
+ throw t;
+ }
- }
- catch (JMSException e)
- {
- log.error("Failed to rollback session transaction", e);
- }
+ }
- }
- }
+ public void error()
+ {
+ // Mark for tollback TX via TM
+ try
+ {
- public void end()
- {
- try
- {
+ if (trace)
+ log.trace(JmsServerSession.this+ " using TM to mark TX for rollback tx=" + trans);
+ trans.setRollbackOnly();
+
+ } catch (Throwable t)
+ {
+ log.error(JmsServerSession.this + " failed to set rollback only", t);
+ }
+ //even if the rollback fails on the transaction, we want to rollback the session.
+ try
+ {
+ session.rollback();
+ } catch (JMSException e)
+ {
+ log.error(JmsServerSession.this + " failed to rollback the transacted session", e);
+ }
- // Use the TM to commit the Tx (assert the correct association)
- Transaction currentTx = tm.getTransaction();
- if (trans.equals(currentTx) == false)
- throw new IllegalStateException("Wrong tx association: expected " + trans + " was " + currentTx);
+ }
- // Marked rollback
- if (trans.getStatus() == Status.STATUS_MARKED_ROLLBACK)
- {
- log.trace(JmsServerSession.this + " rolling Transacted session back due to Transaction Rollback");
- //call to error, if we are rolled back
- error();
- }
+ public void end()
+ {
+ try
+ {
- else if (trans.getStatus() == Status.STATUS_ACTIVE)
- {
- // Commit tx
- // This will happen if
- // a) everything goes well
- // b) app. exception was thrown
- if (trace)
- log.trace(JmsServerSession.this + " commiting the JMS transaction tx=" + trans);
- tm.commit();
+ // Use the TM to commit the Tx (assert the correct association)
+ Transaction currentTx = tm.getTransaction();
+ if (trans.equals(currentTx) == false)
+ throw new IllegalStateException(
+ "Wrong tx association: expected " + trans + " was "
+ + currentTx);
- // NO XASession? then manually commit. This is not so good but
- // it's the best we can do if we have no XASession.
- if (xaSession == null && pool.getActivation().isDeliveryTransacted())
- {
- log.trace(JmsServerSession.this + " commiting Transacted session");
- session.commit();
- }
+ // Marked rollback
+ if (trans.getStatus() == Status.STATUS_MARKED_ROLLBACK)
+ {
+ if (trace)
+ log.trace(JmsServerSession.this
+ + " rolling back JMS transaction tx=" + trans);
+ // actually roll it back
+ tm.rollback();
+ session.rollback();
+ }
- }
- else
- {
- tm.suspend();
+ else if (trans.getStatus() == Status.STATUS_ACTIVE)
+ {
+ // Commit tx
+ // This will happen if
+ // a) everything goes well
+ // b) app. exception was thrown
+ if (trace)
+ log.trace(JmsServerSession.this + " commiting the JMS transaction tx=" + trans);
+ tm.commit();
+ session.commit();
- if (xaSession == null && pool.getActivation().isDeliveryTransacted())
- {
- session.rollback();
- }
+ } else
+ {
+ tm.suspend();
+ session.rollback();
+ }
- }
+ } catch (Throwable t)
+ {
+ log.error(JmsServerSession.this + " failed to commit/rollback", t);
+ //if anything goes wrong with the transaction, we need to rollback the session.
+ try
+ {
+ session.rollback();
+ } catch (JMSException e)
+ {
+ log.error(JmsServerSession.this + " failed to rollback transacted session after transaction failure", t);
+ }
+ }
- }
- catch (Throwable t)
- {
- log.error(JmsServerSession.this + " failed to commit/rollback", t);
- }
+ }
- }
+ }
+ /**
+ * LocalDemaracationStrategy is for anything where the delivery is not marked as transacted.
+ * In CMT the delivery is always marked as transacted. BMT does not mark the delivery as transacted, but
+ * it does mark the session as transacted. BMT uses this class with Transacted sessions in order to rollback or commit the
+ * message.
+ * @author jhowell
+ *
+ */
+ private class LocalDemarcationStrategy implements
+ TransactionDemarcationStrategy
+ {
+ public void end()
+ {
+ final JmsActivationSpec spec = pool.getActivation()
+ .getActivationSpec();
- }
+ if (spec.isSessionTransacted())
+ {
+ if (session != null)
+ {
+ try
+ {
+ session.commit();
+ } catch (JMSException e)
+ {
+ log.error("Failed to commit session transaction", e);
+ }
+ }
+ }
+ }
- private class XATransactionDemarcationStrategy implements
- TransactionDemarcationStrategy
- {
+ public void error()
+ {
+ final JmsActivationSpec spec = pool.getActivation()
+ .getActivationSpec();
- boolean trace = log.isTraceEnabled();
+ if (spec.isSessionTransacted())
+ {
+ if (session != null)
- Transaction trans = null;
+ try
+ {
+ /*
+ * Looks strange, but this basically means
+ *
+ * If the underlying connection was non-XA and the
+ * transaction attribute is REQUIRED we rollback. Also,
+ * if the underlying connection was non-XA and the
+ * transaction attribute is NOT_SUPPORT and the non
+ * standard redelivery behavior is enabled we rollback
+ * to force redelivery.
+ */
+ if (pool.getActivation().isDeliveryTransacted()
+ || spec.getRedeliverUnspecified())
+ {
+ session.rollback();
+ }
- TransactionManager tm = pool.getActivation().getTransactionManager();;
+ } catch (JMSException e)
+ {
+ log.error("Failed to rollback session transaction", e);
+ }
- public XATransactionDemarcationStrategy() throws Throwable
- {
- final int timeout = pool.getActivation().getActivationSpec()
- .getTransactionTimeout();
+ }
+ }
- if (timeout > 0)
- {
- log.trace("Setting transactionTimeout for JMSSessionPool to "
- + timeout);
- tm.setTransactionTimeout(timeout);
+ }
- }
+ /**
+ * This class is used for XATransactions(ie. CMT) for the mdb message delivery. It creates a transaction for the message delivery,
+ * enlists the XASession object in the transaction and then after the on message is called, it will commit/rollback the transaction.
+ * @author jhowell
+ *
+ */
+ private class XATransactionDemarcationStrategy implements
+ TransactionDemarcationStrategy
+ {
- tm.begin();
+ boolean trace = log.isTraceEnabled();
- try
- {
- trans = tm.getTransaction();
+ Transaction trans = null;
- if (trace)
- log.trace(JmsServerSession.this + " using tx=" + trans);
+ TransactionManager tm = pool.getActivation().getTransactionManager();;
- if (xaSession != null)
- {
- XAResource res = xaSession.getXAResource();
+ public XATransactionDemarcationStrategy() throws Throwable
+ {
+ final int timeout = pool.getActivation().getActivationSpec()
+ .getTransactionTimeout();
- if (!trans.enlistResource(res))
- {
- throw new JMSException("could not enlist resource");
- }
- if (trace)
- log.trace(JmsServerSession.this + " XAResource '" + res
- + "' enlisted.");
- }
- } catch (Throwable t)
- {
- try
- {
- tm.rollback();
- } catch (Throwable ignored)
- {
- log.trace(JmsServerSession.this
- + " ignored error rolling back after failed enlist",
- ignored);
- }
- throw t;
- }
+ if (timeout > 0)
+ {
+ log.trace("Setting transactionTimeout for JMSSessionPool to "
+ + timeout);
+ tm.setTransactionTimeout(timeout);
- }
+ }
- public void error()
- {
- // Mark for tollback TX via TM
- try
- {
+ tm.begin();
- if (trace)
- log.trace(JmsServerSession.this
- + " using TM to mark TX for rollback tx=" + trans);
- trans.setRollbackOnly();
- } catch (Throwable t)
- {
- log
- .error(
- JmsServerSession.this + " failed to set rollback only",
- t);
- }
+ try
+ {
+ trans = tm.getTransaction();
- }
+ if (trace)
+ log.trace(JmsServerSession.this + " using tx=" + trans);
- public void end()
- {
- try
- {
+ if (xaSession != null)
+ {
+ XAResource res = xaSession.getXAResource();
- // Use the TM to commit the Tx (assert the correct association)
- Transaction currentTx = tm.getTransaction();
- if (trans.equals(currentTx) == false)
- throw new IllegalStateException(
- "Wrong tx association: expected " + trans + " was "
- + currentTx);
+ if (!trans.enlistResource(res))
+ {
+ throw new JMSException("could not enlist resource");
+ }
+ if (trace)
+ log.trace(JmsServerSession.this + " XAResource '" + res
+ + "' enlisted.");
+ }
+ } catch (Throwable t)
+ {
+ try
+ {
+ tm.rollback();
+ } catch (Throwable ignored)
+ {
+ log
+ .trace(
+ JmsServerSession.this
+ + " ignored error rolling back after failed enlist",
+ ignored);
+ }
+ throw t;
+ }
- // Marked rollback
- if (trans.getStatus() == Status.STATUS_MARKED_ROLLBACK)
- {
- if (trace)
- log.trace(JmsServerSession.this
- + " rolling back JMS transaction tx=" + trans);
- // actually roll it back
- tm.rollback();
+ }
- // NO XASession? then manually rollback.
- // This is not so good but
- // it's the best we can do if we have no XASession.
- if (xaSession == null
- && pool.getActivation().isDeliveryTransacted())
- {
- session.rollback();
- }
- }
-
- else if (trans.getStatus() == Status.STATUS_ACTIVE)
- {
- // Commit tx
- // This will happen if
- // a) everything goes well
- // b) app. exception was thrown
- if (trace)
- log.trace(JmsServerSession.this
- + " commiting the JMS transaction tx=" + trans);
- tm.commit();
+ public void error()
+ {
+ // Mark for tollback TX via TM
+ try
+ {
- // NO XASession? then manually commit. This is not so good but
- // it's the best we can do if we have no XASession.
- if (xaSession == null
- && pool.getActivation().isDeliveryTransacted())
- {
- session.commit();
- }
+ if (trace)
+ log.trace(JmsServerSession.this
+ + " using TM to mark TX for rollback tx=" + trans);
+ trans.setRollbackOnly();
+ } catch (Throwable t)
+ {
+ log.error(JmsServerSession.this
+ + " failed to set rollback only", t);
+ }
- } else
- {
- tm.suspend();
+ }
- if (xaSession == null
- && pool.getActivation().isDeliveryTransacted())
- {
- session.rollback();
- }
+ public void end()
+ {
+ try
+ {
- }
+ // Use the TM to commit the Tx (assert the correct association)
+ Transaction currentTx = tm.getTransaction();
+ if (trans.equals(currentTx) == false)
+ throw new IllegalStateException(
+ "Wrong tx association: expected " + trans + " was "
+ + currentTx);
- } catch (Throwable t)
- {
- log.error(JmsServerSession.this + " failed to commit/rollback", t);
- }
+ // Marked rollback
+ if (trans.getStatus() == Status.STATUS_MARKED_ROLLBACK)
+ {
+ if (trace)
+ log.trace(JmsServerSession.this
+ + " rolling back JMS transaction tx=" + trans);
+ // actually roll it back
+ tm.rollback();
- }
+ // NO XASession? then manually rollback.
+ // This is not so good but
+ // it's the best we can do if we have no XASession.
+ if (xaSession == null
+ && pool.getActivation().isDeliveryTransacted())
+ {
+ session.rollback();
+ }
+ }
- }
-}
+ else if (trans.getStatus() == Status.STATUS_ACTIVE)
+ {
+ // Commit tx
+ // This will happen if
+ // a) everything goes well
+ // b) app. exception was thrown
+ if (trace)
+ log.trace(JmsServerSession.this
+ + " commiting the JMS transaction tx=" + trans);
+ tm.commit();
+
+ // NO XASession? then manually commit. This is not so good
+ // but
+ // it's the best we can do if we have no XASession.
+ if (xaSession == null
+ && pool.getActivation().isDeliveryTransacted())
+ {
+ session.commit();
+ }
+
+ } else
+ {
+ tm.suspend();
+
+ if (xaSession == null
+ && pool.getActivation().isDeliveryTransacted())
+ {
+ session.rollback();
+ }
+
+ }
+
+ } catch (Throwable t)
+ {
+ log.error(JmsServerSession.this + " failed to commit/rollback",
+ t);
+ }
+
+ }
+
+ }
+}
\ No newline at end of file
More information about the jboss-cvs-commits
mailing list