[Jboss-cvs] JBossAS SVN: r55367 - branches/JBoss_3_2_7_JBAS-3467/messaging/src/main/org/jboss/mq/pm/jdbc2
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Mon Aug 7 10:47:45 EDT 2006
Author: luc.texier at jboss.com
Date: 2006-08-07 10:47:43 -0400 (Mon, 07 Aug 2006)
New Revision: 55367
Modified:
branches/JBoss_3_2_7_JBAS-3467/messaging/src/main/org/jboss/mq/pm/jdbc2/PersistenceManager.java
Log:
[JBAS-3467] Add retry logic to handle deadlocks
Modified: branches/JBoss_3_2_7_JBAS-3467/messaging/src/main/org/jboss/mq/pm/jdbc2/PersistenceManager.java
===================================================================
--- branches/JBoss_3_2_7_JBAS-3467/messaging/src/main/org/jboss/mq/pm/jdbc2/PersistenceManager.java 2006-08-07 14:44:33 UTC (rev 55366)
+++ branches/JBoss_3_2_7_JBAS-3467/messaging/src/main/org/jboss/mq/pm/jdbc2/PersistenceManager.java 2006-08-07 14:47:43 UTC (rev 55367)
@@ -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