[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