From 8298d1b493c932705fe0b0d9f61f5887f576f511 Mon Sep 17 00:00:00 2001 From: Felix Wassmer Date: Wed, 5 Apr 2017 18:39:18 +0200 Subject: [PATCH] ARIES-1690: Add Transactional dontRollbackOn/rollbackOn evaluation --- .../aries/transaction/TxInterceptorImpl.java | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/transaction/transaction-blueprint/src/main/java/org/apache/aries/transaction/TxInterceptorImpl.java b/transaction/transaction-blueprint/src/main/java/org/apache/aries/transaction/TxInterceptorImpl.java index 82c7725585..d765fd956e 100644 --- a/transaction/transaction-blueprint/src/main/java/org/apache/aries/transaction/TxInterceptorImpl.java +++ b/transaction/transaction-blueprint/src/main/java/org/apache/aries/transaction/TxInterceptorImpl.java @@ -23,6 +23,7 @@ import javax.transaction.RollbackException; import javax.transaction.Transaction; import javax.transaction.TransactionManager; +import javax.transaction.Transactional; import javax.transaction.Transactional.TxType; import org.apache.aries.blueprint.Interceptor; @@ -77,7 +78,7 @@ public void postCallWithException(ComponentMetadata cm, Method m, Throwable ex, safeEndCoordination(token); try { Transaction tran = token.getActiveTransaction(); - if (tran != null && isRollBackException(ex)) { + if (tran != null && isRollBackException(ex, m)) { tran.setRollbackOnly(); LOGGER.debug("Setting transaction to rollback only because of exception ", ex); } @@ -126,7 +127,39 @@ private static String getCmId(ComponentMetadata cm) { return cm == null ? null : cm.getId(); } - private static boolean isRollBackException(Throwable ex) { + private boolean isRollBackException(Throwable ex, Method m) { + if (m != null) { + Transactional annotation = m.getAnnotation(Transactional.class); + if (annotation == null) { + return isUncheckedException(ex); + } else { + //check dontRollbackOn first, since according to spec it has precedence + Class[] dontRollbackOn = annotation.dontRollbackOn(); + for (Class dontRollbackClass : dontRollbackOn) { + if (dontRollbackClass.isInstance(ex)) { + LOGGER.debug("Current exception {} found in element dontRollbackOn.", ex.getClass()); + return false; + } + } + //don't need to check further elements if ex is an unchecked exception + if (isUncheckedException(ex)) { + return true; + } + Class[] rollbackOn = annotation.rollbackOn(); + for (Class rollbackExceptionClass : rollbackOn) { + if (rollbackExceptionClass.isInstance(ex)) { + LOGGER.debug("Current exception {} found in element rollbackOn.", ex.getClass()); + return true; + } + } + } + } else { + return isUncheckedException(ex); + } + return false; + } + + private static boolean isUncheckedException(Throwable ex) { return ex instanceof RuntimeException || ex instanceof Error; }