[jboss-cvs] JBossAS SVN: r57385 - branches/JBoss_3_2_7_CP/messaging/src/main/org/jboss/mq/pm/jdbc2

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Oct 3 09:40:48 EDT 2006


Author: ryan.campbell at jboss.com
Date: 2006-10-03 09:40:47 -0400 (Tue, 03 Oct 2006)
New Revision: 57385

Modified:
   branches/JBoss_3_2_7_CP/messaging/src/main/org/jboss/mq/pm/jdbc2/PersistenceManager.java
Log:
ASPATCH-71: JBAS-3467: Support Patch for JBAS-3466 - org.jboss.mq.SpyJMSException: Could not remove message when using MySQL DB

Modified: branches/JBoss_3_2_7_CP/messaging/src/main/org/jboss/mq/pm/jdbc2/PersistenceManager.java
===================================================================
--- branches/JBoss_3_2_7_CP/messaging/src/main/org/jboss/mq/pm/jdbc2/PersistenceManager.java	2006-10-03 12:30:59 UTC (rev 57384)
+++ branches/JBoss_3_2_7_CP/messaging/src/main/org/jboss/mq/pm/jdbc2/PersistenceManager.java	2006-10-03 13:40:47 UTC (rev 57385)
@@ -1018,13 +1018,18 @@
       Connection c = null;
       PreparedStatement stmt = null;
       boolean threadWasInterrupted = Thread.interrupted();
+
+      //How many times we retry to execute the statement
+      // in case of a SQLException e.g when deadlock was detected
+      final int MAX_TRIES = 25;
+
       try
       {
          c = this.getConnection();
 
          // Lazily write the peristent transaction
          insertPersistentTx(tms, c, txId);
-         
+
          // Synchronize on the message to avoid a race with the softener
          synchronized (messageRef)
          {
@@ -1033,18 +1038,14 @@
                stmt = c.prepareStatement(DELETE_MESSAGE);
                stmt.setLong(1, messageRef.messageId);
                stmt.setString(2, messageRef.getPersistentKey());
-               int rc = stmt.executeUpdate();
-               if (rc != 1)
-                  throw new SpyJMSException(
-                     "Could not delete the message from the database: delete affected " + rc + " rows");
 
                // Adrian Brock:
-               // Remove the message from the cache, but don't 
+               // Remove the message from the cache, but don't
                // return it to the pool just yet. The queue still holds
                // a reference to the message and will return it
                // to the pool once it gets enough time slice.
                // The alternative is to remove the validation
-               // for double removal from the cache, 
+               // for double removal from the cache,
                // which I don't want to do because it is useful
                // for spotting errors
                messageRef.setStored(MessageReference.NOT_STORED);
@@ -1057,16 +1058,45 @@
                stmt.setString(2, "D");
                stmt.setLong(3, messageRef.messageId);
                stmt.setString(4, messageRef.getPersistentKey());
-               int rc = stmt.executeUpdate();
-               if (rc != 1)
-                  throw new SpyJMSException(
-                     "Could not mark the message as deleted in the database: update affected " + rc + " rows");
             }
-            if (trace)
+
+             int tries = 0;
+             while (true)
+             {
+                try
+                {
+                   int rc = stmt.executeUpdate();
+
+                   if (tries > 0)
+                   {
+                      if (rc != 1)
+                         throw new SpyJMSException(
+                           "Could not mark the message as deleted in the database: update affected " + rc + " rows");
+
+                      log.warn("Remove operation worked after " +tries +" retries");
+                   }
+                   break;
+                }
+                catch (SQLException e)
+                {
+                   log.warn("SQLException caught - assuming deadlock detected, try:" + (tries + 1), e);
+                   tries++;
+                   if (tries == MAX_TRIES)
+                   {
+                      log.error("Retried " + tries + " times, now giving up");
+                      throw new IllegalStateException("Could not remove message after " +tries + "attempts");
+                   }
+                   log.warn("Trying again after a pause");
+                   //Now we wait for a random amount of time to minimise risk of deadlock
+                   Thread.sleep((long)(Math.random() * 500));
+                }
+             }
+
+             if (trace)
                log.trace("Removed message " + messageRef + " transaction=" + txId);
          }
       }
-      catch (SQLException e)
+      catch (Exception e)
       {
          tms.setRollbackOnly();
          throw new SpyJMSException("Could not remove message: " + messageRef, e);
@@ -1075,14 +1105,16 @@
       {
          try
          {
-            stmt.close();
+            if (stmt != null)
+               stmt.close();
          }
          catch (Throwable ignore)
          {
          }
          try
          {
-            c.close();
+            if (c != null)
+               c.close();
          }
          catch (Throwable ignore)
          {




More information about the jboss-cvs-commits mailing list