[jboss-cvs] JBossAS SVN: r83751 - branches/Branch_5_0/connector/src/main/org/jboss/resource/adapter/jms/inflow.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Sun Feb 1 18:04:00 EST 2009


Author: jhowell at redhat.com
Date: 2009-02-01 18:04:00 -0500 (Sun, 01 Feb 2009)
New Revision: 83751

Modified:
   branches/Branch_5_0/connector/src/main/org/jboss/resource/adapter/jms/inflow/JmsServerSession.java
Log:
[JBAS-6431] - Fix [JBAS-6343].  Cleanup fix so that it can be unit tested easier.

Modified: branches/Branch_5_0/connector/src/main/org/jboss/resource/adapter/jms/inflow/JmsServerSession.java
===================================================================
--- branches/Branch_5_0/connector/src/main/org/jboss/resource/adapter/jms/inflow/JmsServerSession.java	2009-02-01 16:27:51 UTC (rev 83750)
+++ branches/Branch_5_0/connector/src/main/org/jboss/resource/adapter/jms/inflow/JmsServerSession.java	2009-02-01 23:04:00 UTC (rev 83751)
@@ -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,78 +323,156 @@
    }
 
    /**
+    * 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();
-         final boolean sessionTransacted = pool.getActivation().getActivationSpec().isSessionTransacted();
+			if (timeout > 0)
+			{
+				log.trace("Setting transactionTimeout for JMSSessionPool to "
+						+ timeout);
+				tm.setTransactionTimeout(timeout);
 
-         if(!sessionTransacted)
-         {
-        	 
-        	 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()
+				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);
+			}
+
+		}
+
+		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);
+
+				// 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 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();
+
+				} 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);
+				}
+			}
+
+		}
+
+	}
+   /**
+    * 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();
 
@@ -400,224 +488,202 @@
 						log.error("Failed to commit session transaction", e);
 					}
 				}
-			} 
-			else
-			{
+			}
+		}
 
-				try
-				{
+		public void error()
+		{
+			final JmsActivationSpec spec = pool.getActivation()
+					.getActivationSpec();
 
-					// 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 (spec.isSessionTransacted())
+			{
+				if (session != null)
 
-					// Marked rollback
-					if (trans.getStatus() == Status.STATUS_MARKED_ROLLBACK)
+					try
 					{
-						log
-								.trace(JmsServerSession.this
-										+ " rolling Transacted session back due to Transaction Rollback");
-						// call to error, if we are rolled back
-						error();
-					}
-
-					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())
+						/*
+						 * 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())
 						{
-							log.trace(JmsServerSession.this
-									+ " commiting Transacted session");
-							session.commit();
+							session.rollback();
 						}
 
-					} else
+					} catch (JMSException e)
 					{
-						tm.suspend();
-
-						if (xaSession == null
-								&& pool.getActivation().isDeliveryTransacted())
-						{
-							session.rollback();
-						}
-
+						log.error("Failed to rollback session transaction", e);
 					}
 
-				} catch (Throwable t)
-				{
-					log.error(JmsServerSession.this
-							+ " failed to commit/rollback", t);
-				}
 			}
 		}
 
 	}
 
-   private class XATransactionDemarcationStrategy implements
-         TransactionDemarcationStrategy
-   {
+	/**
+	 * 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
+	{
 
-      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 XATransactionDemarcationStrategy() throws Throwable
-      {
-         final int timeout = pool.getActivation().getActivationSpec()
-               .getTransactionTimeout();
+		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);
+			if (timeout > 0)
+			{
+				log.trace("Setting transactionTimeout for JMSSessionPool to "
+						+ timeout);
+				tm.setTransactionTimeout(timeout);
 
-         }
+			}
 
-         tm.begin();
+			tm.begin();
 
-         try
-         {
-            trans = tm.getTransaction();
+			try
+			{
+				trans = tm.getTransaction();
 
-            if (trace)
-               log.trace(JmsServerSession.this + " using tx=" + trans);
+				if (trace)
+					log.trace(JmsServerSession.this + " using tx=" + trans);
 
-            if (xaSession != null)
-            {
-               XAResource res = xaSession.getXAResource();
+				if (xaSession != null)
+				{
+					XAResource res = xaSession.getXAResource();
 
-               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 (!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;
+			}
 
-      }
+		}
 
-      public void error()
-      {
-         // Mark for tollback TX via TM
-         try
-         {
+		public void error()
+		{
+			// Mark for tollback TX via TM
+			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);
-         }
+				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);
+			}
 
-      }
+		}
 
-      public void end()
-      {
-         try
-         {
+		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);
+				// 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)
-            {
-               if (trace)
-                  log.trace(JmsServerSession.this
-                        + " rolling back JMS transaction tx=" + trans);
-               // actually roll it back
-               tm.rollback();
+				// 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();
-               }
-            }
+					// 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();
+				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();
-               }
+					// 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();
+				} else
+				{
+					tm.suspend();
 
-               if (xaSession == null
-                     && pool.getActivation().isDeliveryTransacted())
-               {
-                  session.rollback();
-               }
+					if (xaSession == null
+							&& pool.getActivation().isDeliveryTransacted())
+					{
+						session.rollback();
+					}
 
-            }
+				}
 
-         } catch (Throwable t)
-         {
-            log.error(JmsServerSession.this + " failed to commit/rollback", t);
-         }
+			} 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