From 7551a0d4fa9b2543d8b6fdc98c1045a5d13df3b3 Mon Sep 17 00:00:00 2001 From: Gustavo Martin Morcuende Date: Tue, 14 Oct 2014 05:28:20 +0200 Subject: [PATCH] Spring DeadLocks retries --- .../sql/deadlocks/aspect/DeadlockRetryAspect.java | 31 +++++++++++++--------- .../src/main/resources/spring-config.xml | 30 ++++++++++++++++++--- 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/SpringJava/DeadLocksSQL/src/main/java/de/example/sql/deadlocks/aspect/DeadlockRetryAspect.java b/SpringJava/DeadLocksSQL/src/main/java/de/example/sql/deadlocks/aspect/DeadlockRetryAspect.java index c90d9a1..211a061 100644 --- a/SpringJava/DeadLocksSQL/src/main/java/de/example/sql/deadlocks/aspect/DeadlockRetryAspect.java +++ b/SpringJava/DeadLocksSQL/src/main/java/de/example/sql/deadlocks/aspect/DeadlockRetryAspect.java @@ -1,17 +1,16 @@ package de.example.sql.deadlocks.aspect; import java.lang.reflect.Method; +import java.util.Collection; import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.Ordered; -import com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException; - import de.example.sql.deadlocks.annotation.DeadlockRetry; /** @@ -23,6 +22,8 @@ public class DeadlockRetryAspect implements Ordered { private static final Logger logger = LoggerFactory.getLogger(DeadlockRetryAspect.class); private static final int ORDER = 99; + private Collection> retryableExceptionClasses; + @Around(value = "@annotation(deadlockRetry)", argNames = "deadlockRetry") public Object doAround(final ProceedingJoinPoint pjp, final DeadlockRetry deadlockRetry) throws Throwable { @@ -34,29 +35,29 @@ public class DeadlockRetryAspect implements Ordered { final Method method = signature.getMethod(); int count = 0; - Throwable deadLockException = null; + Throwable lastException = null; do { try { count++; logger.info("Attempting to invoke method " + method.getName() + " on " + target.getClass() + " count " + count); //Calling real method - Object result = pjp.proceed(); + final Object result = pjp.proceed(); logger.info("Completed invocation of method " + method.getName() + " on " + target.getClass()); return result; - } catch (final Throwable e1) { + } catch (final Throwable ex) { - if (!isDeadLock(e1)) { - throw e1; + if (!isDeadLock(ex)) { + throw ex; } - deadLockException = e1; + lastException = ex; if (interval > 0) { try { Thread.sleep(interval); - } catch (final InterruptedException e2) { - logger.warn("Deadlock retry thread interrupt", e2); + } catch (final InterruptedException exi) { + logger.warn("Deadlock retry thread interrupt", exi); // Restore interrupt status. Thread.currentThread().interrupt(); @@ -65,7 +66,7 @@ public class DeadlockRetryAspect implements Ordered { } } while (count < maxTries); - throw new RuntimeException("DeadlockRetry failed, deadlock in all retry attempts.", deadLockException); + throw new RuntimeException("DeadlockRetry failed, deadlock in all retry attempts.", lastException); } @Override @@ -73,9 +74,13 @@ public class DeadlockRetryAspect implements Ordered { return ORDER; } + public final void setRetryableExceptionClasses(final Collection> retryableExceptionClasses) { + this.retryableExceptionClasses = retryableExceptionClasses; + } + private boolean isDeadLock(Throwable ex) { do { - if (ex instanceof MySQLTransactionRollbackException) { + if (this.retryableExceptionClasses.contains(ex.getClass())) { return true; } } while ((ex = ex.getCause()) != null); diff --git a/SpringJava/DeadLocksSQL/src/main/resources/spring-config.xml b/SpringJava/DeadLocksSQL/src/main/resources/spring-config.xml index a3d6e2a..637353b 100644 --- a/SpringJava/DeadLocksSQL/src/main/resources/spring-config.xml +++ b/SpringJava/DeadLocksSQL/src/main/resources/spring-config.xml @@ -4,6 +4,7 @@ xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" + xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context @@ -11,7 +12,9 @@ http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx - http://www.springframework.org/schema/tx/spring-tx.xsd"> + http://www.springframework.org/schema/tx/spring-tx.xsd + http://www.springframework.org/schema/util + http://www.springframework.org/schema/util/spring-util.xsd"> - + @@ -41,14 +58,21 @@ need here that feature. I do not really need the component-scan thing but I hope, it will improve performance (not sure) - --> + + I DO NOT THINK component-scan IS INTENDED TO BE USED IN THIS WAY!!!!! + --> + + + com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException + + -- 2.1.4