diff --git a/pom.xml b/pom.xml
index a12d25f..f6c2d5d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -72,8 +72,26 @@
com.inteligr8.alfresco
aspectj-platform-module
- 1.0.0
- provided
+ 1.0.1
+ amp
+
+
+
+
+ org.aspectj
+ aspectjweaver
+ ${aspectj.version}
+ test
+
+
+
+
+ jakarta.transaction
+ jakarta.transaction-api
+
+
+ org.springframework
+ spring-tx
diff --git a/src/main/java/com/inteligr8/alfresco/annotations/TransactionalWrapper.java b/src/main/java/com/inteligr8/alfresco/annotations/TransactionalWrapper.java
new file mode 100644
index 0000000..41f0397
--- /dev/null
+++ b/src/main/java/com/inteligr8/alfresco/annotations/TransactionalWrapper.java
@@ -0,0 +1,113 @@
+package com.inteligr8.alfresco.annotations;
+
+import java.lang.reflect.Method;
+
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+public class TransactionalWrapper {
+
+ private Transactional stxl = null;
+ private javax.transaction.Transactional jtxl = null;
+
+ public TransactionalWrapper(Transactional txl) {
+ this.stxl = txl;
+ }
+
+ public TransactionalWrapper(javax.transaction.Transactional txl) {
+ this.jtxl = txl;
+ }
+
+ public static TransactionalWrapper wrap(Method method) {
+ Transactional stxl = method.getAnnotation(Transactional.class);
+ javax.transaction.Transactional jtxl = method.getAnnotation(javax.transaction.Transactional.class);
+ if (stxl == null && jtxl == null) {
+ return null;
+ } else if (stxl != null) {
+ return new TransactionalWrapper(stxl);
+ } else if (jtxl != null) {
+ return new TransactionalWrapper(jtxl);
+ } else {
+ throw new IllegalStateException("This should never happen");
+ }
+ }
+
+ public boolean isReadOnly() {
+ if (this.stxl != null) {
+ return this.stxl.readOnly();
+ } else if (this.jtxl != null) {
+ return false;
+ } else {
+ throw new IllegalStateException("This should never happen");
+ }
+ }
+
+ public Propagation getPropagation() {
+ if (this.stxl != null) {
+ return this.stxl.propagation();
+ } else if (this.jtxl != null) {
+ switch (this.jtxl.value()) {
+ case MANDATORY:
+ return Propagation.MANDATORY;
+ case REQUIRED:
+ return Propagation.REQUIRED;
+ case REQUIRES_NEW:
+ return Propagation.REQUIRES_NEW;
+ case SUPPORTS:
+ return Propagation.SUPPORTS;
+ case NOT_SUPPORTED:
+ return Propagation.NOT_SUPPORTED;
+ case NEVER:
+ return Propagation.NEVER;
+ default:
+ throw new IllegalStateException("This should never happen");
+ }
+ } else {
+ throw new IllegalStateException("This should never happen");
+ }
+ }
+
+ public Isolation getIsolation() {
+ if (this.stxl != null) {
+ return this.stxl.isolation();
+ } else if (this.jtxl != null) {
+ return Isolation.DEFAULT;
+ } else {
+ throw new IllegalStateException("This should never happen");
+ }
+ }
+
+ public int getTimeoutInSeconds() {
+ if (this.stxl != null) {
+ return this.stxl.timeout();
+ } else if (this.jtxl != null) {
+ return 0;
+ } else {
+ throw new IllegalStateException("This should never happen");
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public Class extends Throwable>[] getRollbackFor() {
+ if (this.stxl != null) {
+ return this.stxl.rollbackFor();
+ } else if (this.jtxl != null) {
+ return this.jtxl.rollbackOn();
+ } else {
+ throw new IllegalStateException("This should never happen");
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public Class extends Throwable>[] getNoRollbackFor() {
+ if (this.stxl != null) {
+ return this.stxl.noRollbackFor();
+ } else if (this.jtxl != null) {
+ return this.jtxl.dontRollbackOn();
+ } else {
+ throw new IllegalStateException("This should never happen");
+ }
+ }
+
+}
diff --git a/src/main/java/com/inteligr8/alfresco/annotations/aspect/RetryingTransactionAspect.java b/src/main/java/com/inteligr8/alfresco/annotations/aspect/RetryingTransactionAspect.java
index 5de69e4..2e83d92 100644
--- a/src/main/java/com/inteligr8/alfresco/annotations/aspect/RetryingTransactionAspect.java
+++ b/src/main/java/com/inteligr8/alfresco/annotations/aspect/RetryingTransactionAspect.java
@@ -17,9 +17,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.IllegalTransactionStateException;
-import org.springframework.transaction.annotation.Transactional;
import com.inteligr8.alfresco.annotations.TransactionalRetryable;
+import com.inteligr8.alfresco.annotations.TransactionalWrapper;
/**
* This aspect implements the @Transactional and @TransactionalRetryable
@@ -50,20 +50,24 @@ public class RetryingTransactionAspect {
public void isTransactionalAnnotated() {
}
+ @Pointcut("@annotation(javax.transaction.Transactional) && execution(* *(..))")
+ public void isJtaTransactionalAnnotated() {
+ }
+
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.TransactionalRetryable) && execution(* *(..))")
public void isTransactionalRetryableAnnotated() {
}
- @Around("isTransactionalAnnotated() || isTransactionalRetryableAnnotated()")
+ @Around("isTransactionalAnnotated() || isJtaTransactionalAnnotated() || isTransactionalRetryableAnnotated()")
public Object retryingTransactional(ProceedingJoinPoint joinPoint) throws Throwable {
this.logger.trace("retryingTransactional({})", joinPoint);
Method method = this.getMethod(joinPoint);
- Transactional txl = method.getAnnotation(Transactional.class);
+ TransactionalWrapper txl = TransactionalWrapper.wrap(method);
TransactionalRetryable txtry = method.getAnnotation(TransactionalRetryable.class);
if (this.doCreateNewTxContext(txl) || this.isReadStateChange(txl)) {
- this.logger.debug("Changing TX context: {} => [ro: {}, new: {}]", AlfrescoTransactionSupport.getTransactionReadState(), txl.readOnly(), txl.propagation());
+ this.logger.debug("Changing TX context: {} => [ro: {}, new: {}]", AlfrescoTransactionSupport.getTransactionReadState(), txl.isReadOnly(), txl.getPropagation());
return this.execute(joinPoint, txl, txtry);
} else if (this.doCreateNewTxRetryContext(txtry)) {
this.logger.debug("Changing TX context: retries: {}", txtry.maxRetries());
@@ -81,11 +85,11 @@ public class RetryingTransactionAspect {
return methodSig.getMethod();
}
- private boolean isReadStateChange(Transactional txl) {
+ private boolean isReadStateChange(TransactionalWrapper txl) {
if (txl == null)
return false;
- switch (txl.propagation()) {
+ switch (txl.getPropagation()) {
case NEVER:
case NOT_SUPPORTED:
case SUPPORTS:
@@ -98,9 +102,9 @@ public class RetryingTransactionAspect {
case TXN_NONE:
return true;
case TXN_READ_ONLY:
- return !txl.readOnly();
+ return !txl.isReadOnly();
case TXN_READ_WRITE:
- return txl.readOnly();
+ return txl.isReadOnly();
default:
throw new IllegalStateException();
}
@@ -110,10 +114,10 @@ public class RetryingTransactionAspect {
return txtry != null;
}
- private boolean doCreateNewTxContext(Transactional txl) {
+ private boolean doCreateNewTxContext(TransactionalWrapper txl) {
if (txl == null) {
return false;
- } else switch (txl.propagation()) {
+ } else switch (txl.getPropagation()) {
case NEVER:
switch (AlfrescoTransactionSupport.getTransactionReadState()) {
case TXN_NONE:
@@ -126,10 +130,10 @@ public class RetryingTransactionAspect {
case TXN_NONE:
throw new IllegalTransactionStateException("A transaction does not exist where one is mandatory");
case TXN_READ_ONLY:
- if (!txl.readOnly())
+ if (!txl.isReadOnly())
throw new IllegalTransactionStateException("A read-only transaction exists where a read/write one is mandatory");
case TXN_READ_WRITE:
- if (txl.readOnly())
+ if (txl.isReadOnly())
throw new IllegalTransactionStateException("A read/write transaction exists where a read-only one is mandatory");
}
case SUPPORTS:
@@ -145,11 +149,11 @@ public class RetryingTransactionAspect {
case REQUIRES_NEW:
return true;
default:
- throw new IllegalTransactionStateException("The transactional propagation is not supported: " + txl.propagation());
+ throw new IllegalTransactionStateException("The transactional propagation is not supported: " + txl.getPropagation());
}
}
- private Object execute(final ProceedingJoinPoint joinPoint, Transactional txl, TransactionalRetryable txtry) throws Throwable {
+ private Object execute(final ProceedingJoinPoint joinPoint, TransactionalWrapper txl, TransactionalRetryable txtry) throws Throwable {
RetryingTransactionCallback