Created
January 30, 2015 19:21
-
-
Save alexey-su/d1b05460c7fc59aab60e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/main/java/org/mybatis/guice/AbstractMyBatisModule.java b/src/main/java/org/mybatis/guice/AbstractMyBatisModule.java | |
index 6b9c745..fd71db7 100644 | |
--- a/src/main/java/org/mybatis/guice/AbstractMyBatisModule.java | |
+++ b/src/main/java/org/mybatis/guice/AbstractMyBatisModule.java | |
@@ -25,6 +25,7 @@ import org.mybatis.guice.mappers.MapperProvider; | |
import org.mybatis.guice.session.SqlSessionManagerProvider; | |
import org.mybatis.guice.transactional.Transactional; | |
import org.mybatis.guice.transactional.TransactionalMethodInterceptor; | |
+import org.mybatis.guice.transactional.TxTransactionalMethodInterceptor; | |
import java.lang.reflect.Method; | |
@@ -60,14 +61,7 @@ abstract class AbstractMyBatisModule extends AbstractModule { | |
bind(SqlSessionManager.class).toProvider(SqlSessionManagerProvider.class).in(Scopes.SINGLETON); | |
bind(SqlSession.class).to(SqlSessionManager.class).in(Scopes.SINGLETON); | |
- // transactional interceptor | |
- TransactionalMethodInterceptor interceptor = new TransactionalMethodInterceptor(); | |
- requestInjection(interceptor); | |
- bindInterceptor(any(), not(DECLARED_BY_OBJECT).and(annotatedWith(Transactional.class)), interceptor); | |
- // Intercept classes annotated with Transactional, but avoid "double" | |
- // interception when a mathod is also annotated inside an annotated | |
- // class. | |
- bindInterceptor(annotatedWith(Transactional.class), not(DECLARED_BY_OBJECT).and(not(annotatedWith(Transactional.class))), interceptor); | |
+ bindTransactionInterceptors(); | |
internalConfigure(); | |
@@ -79,6 +73,21 @@ abstract class AbstractMyBatisModule extends AbstractModule { | |
driverClassLoader = getDefaultClassLoader(); | |
} | |
} | |
+ | |
+ /** | |
+ * bind transactional interceptors | |
+ */ | |
+ protected void bindTransactionInterceptors() { | |
+ // transactional interceptor | |
+ TransactionalMethodInterceptor interceptor = new TransactionalMethodInterceptor(); | |
+ requestInjection(interceptor); | |
+ | |
+ bindInterceptor(any(), annotatedWith(Transactional.class), interceptor); | |
+ // Intercept classes annotated with Transactional, but avoid "double" | |
+ // interception when a mathod is also annotated inside an annotated | |
+ // class. | |
+ bindInterceptor(annotatedWith(Transactional.class), not(annotatedWith(Transactional.class)), interceptor); | |
+ } | |
/** | |
* | |
diff --git a/src/main/java/org/mybatis/guice/MyBatisJtaModule.java b/src/main/java/org/mybatis/guice/MyBatisJtaModule.java | |
new file mode 100644 | |
index 0000000..45d7574 | |
--- /dev/null | |
+++ b/src/main/java/org/mybatis/guice/MyBatisJtaModule.java | |
@@ -0,0 +1,80 @@ | |
+package org.mybatis.guice; | |
+ | |
+import static com.google.inject.matcher.Matchers.annotatedWith; | |
+import static com.google.inject.matcher.Matchers.any; | |
+import static com.google.inject.matcher.Matchers.not; | |
+ | |
+import javax.inject.Provider; | |
+import javax.transaction.TransactionManager; | |
+ | |
+import org.apache.ibatis.transaction.TransactionFactory; | |
+import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; | |
+import org.apache.ibatis.transaction.managed.ManagedTransactionFactory; | |
+import org.mybatis.guice.transactional.Transactional; | |
+import org.mybatis.guice.transactional.TransactionalMethodInterceptor; | |
+import org.mybatis.guice.transactional.TxTransactionalMethodInterceptor; | |
+ | |
+public abstract class MyBatisJtaModule extends MyBatisModule { | |
+ | |
+ private TransactionManager transactionManager; | |
+ | |
+ | |
+ public MyBatisJtaModule() { | |
+ } | |
+ | |
+ public MyBatisJtaModule(TransactionManager transactionManager) { | |
+ this.transactionManager = transactionManager; | |
+ } | |
+ | |
+ @Override | |
+ protected void bindTransactionInterceptors() { | |
+ TransactionManager manager = getTransactionManager(); | |
+ | |
+ if(manager == null) { | |
+ super.bindTransactionInterceptors(); | |
+ } else { | |
+ // mybatis transactional interceptor | |
+ TransactionalMethodInterceptor interceptor = new TransactionalMethodInterceptor(); | |
+ requestInjection(interceptor); | |
+ | |
+ // jta transactional interceptor | |
+ TxTransactionalMethodInterceptor interceptorTx = new TxTransactionalMethodInterceptor(); | |
+ requestInjection(interceptorTx); | |
+ | |
+ bind(TransactionManager.class).toInstance(manager); | |
+ bindInterceptor(any(), annotatedWith(Transactional.class), interceptorTx, interceptor); | |
+ // Intercept classes annotated with Transactional, but avoid "double" | |
+ // interception when a mathod is also annotated inside an annotated | |
+ // class. | |
+ bindInterceptor(annotatedWith(Transactional.class), not(annotatedWith(Transactional.class)), interceptorTx, interceptor); | |
+ } | |
+ } | |
+ | |
+ protected TransactionManager getTransactionManager() { | |
+ return transactionManager; | |
+ } | |
+ | |
+ protected void setTransactionManager(TransactionManager transactionManager) { | |
+ this.transactionManager = transactionManager; | |
+ } | |
+ | |
+ protected void bindDefaultTransactionProvider() { | |
+ Class<? extends TransactionFactory> factoryType = getTransactionManager() == null ? | |
+ JdbcTransactionFactory.class : ManagedTransactionFactory.class; | |
+ | |
+ bindTransactionFactoryType(factoryType); | |
+ } | |
+ | |
+ protected static class ProviderImpl<T> implements Provider<T> { | |
+ private T wrapper; | |
+ | |
+ public ProviderImpl(T wrapper) { | |
+ this.wrapper = wrapper; | |
+ } | |
+ | |
+ public T get() { | |
+ return wrapper; | |
+ } | |
+ | |
+ } | |
+} | |
diff --git a/src/main/java/org/mybatis/guice/transactional/TransactionAttribute.java b/src/main/java/org/mybatis/guice/transactional/TransactionAttribute.java | |
new file mode 100644 | |
index 0000000..07b4cc7 | |
--- /dev/null | |
+++ b/src/main/java/org/mybatis/guice/transactional/TransactionAttribute.java | |
@@ -0,0 +1,174 @@ | |
+/* | |
+ * Licensed to the Apache Software Foundation (ASF) under one | |
+ * or more contributor license agreements. See the NOTICE file | |
+ * distributed with this work for additional information | |
+ * regarding copyright ownership. The ASF licenses this file | |
+ * to you under the Apache License, Version 2.0 (the | |
+ * "License"); you may not use this file except in compliance | |
+ * with the License. You may obtain a copy of the License at | |
+ * | |
+ * http://www.apache.org/licenses/LICENSE-2.0 | |
+ * | |
+ * Unless required by applicable law or agreed to in writing, | |
+ * software distributed under the License is distributed on an | |
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
+ * KIND, either express or implied. See the License for the | |
+ * specific language governing permissions and limitations | |
+ * under the License. | |
+ */ | |
+package org.mybatis.guice.transactional; | |
+ | |
+import javax.transaction.HeuristicMixedException; | |
+import javax.transaction.HeuristicRollbackException; | |
+import javax.transaction.InvalidTransactionException; | |
+import javax.transaction.NotSupportedException; | |
+import javax.transaction.RollbackException; | |
+import javax.transaction.Status; | |
+import javax.transaction.SystemException; | |
+import javax.transaction.Transaction; | |
+import javax.transaction.TransactionManager; | |
+ | |
+public enum TransactionAttribute { | |
+ MANDATORY | |
+ { | |
+ @Override | |
+ public TransactionToken begin(TransactionManager man) throws SystemException | |
+ { | |
+ if (man.getStatus() == Status.STATUS_NO_TRANSACTION) { | |
+ throw new IllegalStateException( | |
+ "A call is being made on a method that mandates a transaction but there is no current transaction."); | |
+ } | |
+ return new TransactionToken(man.getTransaction(), null, MANDATORY); | |
+ } | |
+ }, | |
+ NEVER | |
+ { | |
+ @Override | |
+ public TransactionToken begin(TransactionManager man) throws SystemException | |
+ { | |
+ if (man.getStatus() == Status.STATUS_ACTIVE) { | |
+ throw new IllegalStateException( | |
+ "A call is being made on a method that forbids a transaction but there is a current transaction."); | |
+ } | |
+ return new TransactionToken(null, null, NEVER); | |
+ } | |
+ }, | |
+ NOTSUPPORTED { | |
+ @Override | |
+ public TransactionToken begin(TransactionManager man) throws SystemException { | |
+ if (man.getStatus() == Status.STATUS_ACTIVE) { | |
+ return new TransactionToken(null, man.suspend(), this); | |
+ } | |
+ return new TransactionToken(null, null, NOTSUPPORTED); | |
+ } | |
+ | |
+ @Override | |
+ public void finish(TransactionManager man, TransactionToken tranToken) throws SystemException, | |
+ InvalidTransactionException, IllegalStateException { | |
+ Transaction tran = tranToken.getSuspendedTransaction(); | |
+ if (tran != null) { | |
+ man.resume(tran); | |
+ } | |
+ } | |
+ }, | |
+ REQUIRED { | |
+ @Override | |
+ public TransactionToken begin(TransactionManager man) throws SystemException, NotSupportedException { | |
+ if (man.getStatus() == Status.STATUS_NO_TRANSACTION) { | |
+ man.begin(); | |
+ return new TransactionToken(man.getTransaction(), null, REQUIRED, true); | |
+ } | |
+ return new TransactionToken(man.getTransaction(), null, REQUIRED); | |
+ } | |
+ | |
+ @Override | |
+ public void finish(TransactionManager man, TransactionToken tranToken) throws SystemException, | |
+ InvalidTransactionException, IllegalStateException, SecurityException, RollbackException, | |
+ HeuristicMixedException, HeuristicRollbackException { | |
+ | |
+ if (tranToken.isCompletionAllowed()) { | |
+ if (man.getStatus() == Status.STATUS_MARKED_ROLLBACK) { | |
+ man.rollback(); | |
+ } else { | |
+ man.commit(); | |
+ } | |
+ } | |
+ } | |
+ }, | |
+ REQUIRESNEW | |
+ { | |
+ @Override | |
+ public TransactionToken begin(TransactionManager man) throws SystemException, NotSupportedException, | |
+ InvalidTransactionException, IllegalStateException | |
+ { | |
+ TransactionToken tranToken; | |
+ if (man.getStatus() == Status.STATUS_ACTIVE) { | |
+ tranToken = new TransactionToken(null, man.suspend(), REQUIRESNEW); | |
+ } else { | |
+ tranToken = new TransactionToken(null, null, REQUIRESNEW); | |
+ } | |
+ | |
+ try { | |
+ man.begin(); | |
+ } catch (SystemException e) { | |
+ man.resume(tranToken.getSuspendedTransaction()); | |
+ throw e; | |
+ } catch (NotSupportedException e) { | |
+ man.resume(tranToken.getSuspendedTransaction()); | |
+ throw e; | |
+ } | |
+ | |
+ tranToken.setActiveTransaction(man.getTransaction()); | |
+ tranToken.setCompletionAllowed(true); | |
+ | |
+ return tranToken; | |
+ } | |
+ | |
+ @Override | |
+ public void finish(TransactionManager man, TransactionToken tranToken) throws SystemException, | |
+ InvalidTransactionException, IllegalStateException, SecurityException, RollbackException, | |
+ HeuristicMixedException, HeuristicRollbackException | |
+ { | |
+ if (tranToken.isCompletionAllowed()) { | |
+ if (man.getStatus() == Status.STATUS_MARKED_ROLLBACK) { | |
+ man.rollback(); | |
+ } else { | |
+ man.commit(); | |
+ } | |
+ } | |
+ | |
+ Transaction tran = tranToken.getSuspendedTransaction(); | |
+ if (tran != null) { | |
+ man.resume(tran); | |
+ } | |
+ } | |
+ }, | |
+ SUPPORTS { | |
+ @Override | |
+ public TransactionToken begin(TransactionManager man) throws SystemException, NotSupportedException, | |
+ InvalidTransactionException, IllegalStateException | |
+ { | |
+ if (man.getStatus() == Status.STATUS_ACTIVE) { | |
+ return new TransactionToken(man.getTransaction(), null, SUPPORTS); | |
+ } | |
+ | |
+ return new TransactionToken(null, null, SUPPORTS); | |
+ } | |
+ }; | |
+ | |
+ public static TransactionAttribute fromValue(String value) { | |
+ return valueOf(value.toUpperCase()); | |
+ } | |
+ | |
+ public TransactionToken begin(TransactionManager man) throws SystemException, NotSupportedException, | |
+ InvalidTransactionException, IllegalStateException { | |
+ | |
+ return null; | |
+ } | |
+ | |
+ public void finish(TransactionManager man, TransactionToken tranToken) throws SystemException, | |
+ InvalidTransactionException, IllegalStateException, SecurityException, RollbackException, | |
+ HeuristicMixedException, HeuristicRollbackException { | |
+ | |
+ } | |
+} | |
diff --git a/src/main/java/org/mybatis/guice/transactional/TransactionToken.java b/src/main/java/org/mybatis/guice/transactional/TransactionToken.java | |
new file mode 100644 | |
index 0000000..8b1f364 | |
--- /dev/null | |
+++ b/src/main/java/org/mybatis/guice/transactional/TransactionToken.java | |
@@ -0,0 +1,73 @@ | |
+/* | |
+ * Licensed to the Apache Software Foundation (ASF) under one | |
+ * or more contributor license agreements. See the NOTICE file | |
+ * distributed with this work for additional information | |
+ * regarding copyright ownership. The ASF licenses this file | |
+ * to you under the Apache License, Version 2.0 (the | |
+ * "License"); you may not use this file except in compliance | |
+ * with the License. You may obtain a copy of the License at | |
+ * | |
+ * http://www.apache.org/licenses/LICENSE-2.0 | |
+ * | |
+ * Unless required by applicable law or agreed to in writing, | |
+ * software distributed under the License is distributed on an | |
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
+ * KIND, either express or implied. See the License for the | |
+ * specific language governing permissions and limitations | |
+ * under the License. | |
+ */ | |
+package org.mybatis.guice.transactional; | |
+ | |
+import javax.transaction.Transaction; | |
+ | |
+public class TransactionToken { | |
+ private Transaction activeTransaction; | |
+ private Transaction suspendedTransaction; | |
+ private TransactionAttribute transactionAttribute; | |
+ private boolean isCompletionAllowed; | |
+ | |
+ public TransactionToken(Transaction activeTransaction, Transaction suspendedTransaction, | |
+ TransactionAttribute transactionAttribute) { | |
+ this(activeTransaction, suspendedTransaction, transactionAttribute, false); | |
+ } | |
+ | |
+ TransactionToken(Transaction activeTransaction, Transaction suspendedTransaction, | |
+ TransactionAttribute transactionAttribute, boolean isCompletionAllowed) { | |
+ this.activeTransaction = activeTransaction; | |
+ this.suspendedTransaction = suspendedTransaction; | |
+ this.transactionAttribute = transactionAttribute; | |
+ this.isCompletionAllowed = isCompletionAllowed; | |
+ } | |
+ | |
+ public Transaction getActiveTransaction() { | |
+ return activeTransaction; | |
+ } | |
+ | |
+ public void setActiveTransaction(Transaction activeTransaction) { | |
+ this.activeTransaction = activeTransaction; | |
+ } | |
+ | |
+ public Transaction getSuspendedTransaction() { | |
+ return suspendedTransaction; | |
+ } | |
+ | |
+ public void setSuspendedTransaction(Transaction suspendedTransaction) { | |
+ this.suspendedTransaction = suspendedTransaction; | |
+ } | |
+ | |
+ public TransactionAttribute getTransactionAttribute() { | |
+ return transactionAttribute; | |
+ } | |
+ | |
+ public void setTransactionStrategy(TransactionAttribute transactionAttribute) { | |
+ this.transactionAttribute = transactionAttribute; | |
+ } | |
+ | |
+ public boolean isCompletionAllowed() { | |
+ return isCompletionAllowed; | |
+ } | |
+ | |
+ public void setCompletionAllowed(boolean isCompletionAllowed) { | |
+ this.isCompletionAllowed = isCompletionAllowed; | |
+ } | |
+} | |
diff --git a/src/main/java/org/mybatis/guice/transactional/Transactional.java b/src/main/java/org/mybatis/guice/transactional/Transactional.java | |
index 970f768..87883a5 100644 | |
--- a/src/main/java/org/mybatis/guice/transactional/Transactional.java | |
+++ b/src/main/java/org/mybatis/guice/transactional/Transactional.java | |
@@ -101,4 +101,103 @@ public @interface Transactional { | |
*/ | |
boolean rollbackOnly() default false; | |
+ // | |
+ // from javax.transaction.Transactional | |
+ // | |
+ | |
+ /** | |
+ * The TxType element of the Transactional annotation indicates whether a bean method | |
+ * is to be executed within a transaction context. | |
+ */ | |
+ TxType value() default TxType.REQUIRED; | |
+ | |
+ /** | |
+ * The TxType element of the annotation indicates whether a bean method is to be | |
+ * executed within a transaction context where the values provide the following | |
+ * corresponding behavior. | |
+ */ | |
+ public enum TxType { | |
+ /** | |
+ * <p>If called outside a transaction context, the interceptor must begin a new | |
+ * JTA transaction, the managed bean method execution must then continue | |
+ * inside this transaction context, and the transaction must be completed by | |
+ * the interceptor.</p> | |
+ * <p>If called inside a transaction context, the managed bean | |
+ * method execution must then continue inside this transaction context.</p> | |
+ */ | |
+ REQUIRED, | |
+ | |
+ /** | |
+ * <p>If called outside a transaction context, the interceptor must begin a new | |
+ * JTA transaction, the managed bean method execution must then continue | |
+ * inside this transaction context, and the transaction must be completed by | |
+ * the interceptor.</p> | |
+ * <p>If called inside a transaction context, the current transaction context must | |
+ * be suspended, a new JTA transaction will begin, the managed bean method | |
+ * execution must then continue inside this transaction context, the transaction | |
+ * must be completed, and the previously suspended transaction must be resumed.</p> | |
+ */ | |
+ REQUIRES_NEW, | |
+ | |
+ /** | |
+ * <p>If called outside a transaction context, a TransactionalException with a | |
+ * nested TransactionRequiredException must be thrown.</p> | |
+ * <p>If called inside a transaction context, managed bean method execution will | |
+ * then continue under that context.</p> | |
+ */ | |
+ MANDATORY, | |
+ | |
+ /** | |
+ * <p>If called outside a transaction context, managed bean method execution | |
+ * must then continue outside a transaction context.</p> | |
+ * <p>If called inside a transaction context, the managed bean method execution | |
+ * must then continue inside this transaction context.</p> | |
+ */ | |
+ SUPPORTS, | |
+ | |
+ /** | |
+ * <p>If called outside a transaction context, managed bean method execution | |
+ * must then continue outside a transaction context.</p> | |
+ * <p>If called inside a transaction context, the current transaction context must | |
+ * be suspended, the managed bean method execution must then continue | |
+ * outside a transaction context, and the previously suspended transaction | |
+ * must be resumed by the interceptor that suspended it after the method | |
+ * execution has completed.</p> | |
+ */ | |
+ NOT_SUPPORTED, | |
+ | |
+ /** | |
+ * <p>If called outside a transaction context, managed bean method execution | |
+ * must then continue outside a transaction context.</p> | |
+ * <p>If called inside a transaction context, a TransactionalException with | |
+ * a nested InvalidTransactionException must be thrown.</p> | |
+ */ | |
+ NEVER | |
+ } | |
+ | |
+ /** | |
+ * The rollbackOn element can be set to indicate exceptions that must cause | |
+ * the interceptor to mark the transaction for rollback. Conversely, the dontRollbackOn | |
+ * element can be set to indicate exceptions that must not cause the interceptor to mark | |
+ * the transaction for rollback. When a class is specified for either of these elements, | |
+ * the designated behavior applies to subclasses of that class as well. If both elements | |
+ * are specified, dontRollbackOn takes precedence. | |
+ * @return Class[] of Exceptions | |
+ */ | |
+ // @Nonbinding | |
+ // public Class[] rollbackOn() default {}; | |
+ | |
+ /** | |
+ * The dontRollbackOn element can be set to indicate exceptions that must not cause | |
+ * the interceptor to mark the transaction for rollback. Conversely, the rollbackOn element | |
+ * can be set to indicate exceptions that must cause the interceptor to mark the transaction | |
+ * for rollback. When a class is specified for either of these elements, | |
+ * the designated behavior applies to subclasses of that class as well. If both elements | |
+ * are specified, dontRollbackOn takes precedence. | |
+ * @return Class[] of Exceptions | |
+ */ | |
+ // @Nonbinding | |
+ // public Class[] dontRollbackOn() default {}; | |
+ | |
+ | |
} | |
diff --git a/src/main/java/org/mybatis/guice/transactional/TxTransactionalMethodInterceptor.java b/src/main/java/org/mybatis/guice/transactional/TxTransactionalMethodInterceptor.java | |
new file mode 100644 | |
index 0000000..fdc991c | |
--- /dev/null | |
+++ b/src/main/java/org/mybatis/guice/transactional/TxTransactionalMethodInterceptor.java | |
@@ -0,0 +1,134 @@ | |
+/* | |
+ * Copyright 2010-2014 The MyBatis Team | |
+ * | |
+ * Licensed under the Apache License, Version 2.0 (the "License"); | |
+ * you may not use this file except in compliance with the License. | |
+ * You may obtain a copy of the License at | |
+ * | |
+ * http://www.apache.org/licenses/LICENSE-2.0 | |
+ * | |
+ * Unless required by applicable law or agreed to in writing, software | |
+ * distributed under the License is distributed on an "AS IS" BASIS, | |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
+ * See the License for the specific language governing permissions and | |
+ * limitations under the License. | |
+ */ | |
+package org.mybatis.guice.transactional; | |
+ | |
+import static java.lang.String.format; | |
+ | |
+import java.lang.reflect.Method; | |
+ | |
+import javax.inject.Inject; | |
+import javax.transaction.TransactionManager; | |
+ | |
+import org.aopalliance.intercept.MethodInterceptor; | |
+import org.aopalliance.intercept.MethodInvocation; | |
+import org.apache.ibatis.logging.Log; | |
+import org.apache.ibatis.logging.LogFactory; | |
+import org.mybatis.guice.transactional.Transactional.TxType; | |
+ | |
+/** | |
+ * Method interceptor for {@link Transactional} annotation. | |
+ * | |
+ */ | |
+public class TxTransactionalMethodInterceptor implements MethodInterceptor { | |
+ /** | |
+ * This class logger. | |
+ */ | |
+ private final Log log = LogFactory.getLog(getClass()); | |
+ | |
+ @Inject private TransactionManager manager; | |
+ | |
+ public TxTransactionalMethodInterceptor() { | |
+ } | |
+ | |
+ /** | |
+ * {@inheritDoc} | |
+ */ | |
+ public Object invoke(MethodInvocation invocation) throws Throwable { | |
+ Method interceptedMethod = invocation.getMethod(); | |
+ Transactional transactional = interceptedMethod.getAnnotation(Transactional.class); | |
+ | |
+ // The annotation may be present at the class level instead | |
+ if (transactional == null) { | |
+ transactional = interceptedMethod.getDeclaringClass().getAnnotation(Transactional.class); | |
+ } | |
+ | |
+ String debugPrefix = null; | |
+ if (this.log.isDebugEnabled()) { | |
+ debugPrefix = String.format("[Intercepted method: %s]", interceptedMethod.toGenericString()); | |
+ } | |
+ | |
+ Object object = null; | |
+ TransactionAttribute attribute = null; | |
+ | |
+ if(manager != null) { | |
+ TxType txType = transactional.value(); | |
+ if(TxType.REQUIRED.equals(txType)) | |
+ attribute = TransactionAttribute.REQUIRED; | |
+ else if(TxType.REQUIRES_NEW.equals(txType)) | |
+ attribute = TransactionAttribute.REQUIRESNEW; | |
+ else if(TxType.MANDATORY.equals(txType)) | |
+ attribute = TransactionAttribute.MANDATORY; | |
+ else if(TxType.SUPPORTS.equals(txType)) | |
+ attribute = TransactionAttribute.SUPPORTS; | |
+ else if(TxType.NOT_SUPPORTED.equals(txType)) | |
+ attribute = null; // FIXME add implementation | |
+ else if(TxType.NEVER.equals(txType)) | |
+ attribute = TransactionAttribute.NEVER; | |
+ } | |
+ | |
+ if(attribute == null) { | |
+ if(log.isDebugEnabled()) { | |
+ log.debug(format("%s - skip Tx Transaction", debugPrefix)); | |
+ } | |
+ | |
+ // without Tx | |
+ try { | |
+ object = invocation.proceed(); | |
+ } catch (Throwable t) { | |
+ throw t; | |
+ } | |
+ } else { | |
+ if(log.isDebugEnabled()) { | |
+ log.debug(format("%s - Tx Transaction %s begin", | |
+ debugPrefix, | |
+ attribute.name())); | |
+ } | |
+ | |
+ // with Tx | |
+ TransactionToken tranToken = attribute.begin(manager); | |
+ | |
+ try { | |
+ if(log.isDebugEnabled()) { | |
+ log.debug(format("%s - Tx Transaction %s (CompletionAllowed %s) call method", | |
+ debugPrefix, | |
+ attribute.name(), | |
+ tranToken.isCompletionAllowed())); | |
+ } | |
+ object = invocation.proceed(); | |
+ | |
+ } catch (Throwable t) { | |
+ if(log.isDebugEnabled()) { | |
+ log.debug(format("%s - Tx Transaction %s (CompletionAllowed %s) rolling back", | |
+ debugPrefix, | |
+ attribute.name(), | |
+ tranToken.isCompletionAllowed())); | |
+ } | |
+ manager.setRollbackOnly(); | |
+ throw t; | |
+ } finally { | |
+ if(log.isDebugEnabled()) { | |
+ log.debug(format("%s - Tx Transaction %s (CompletionAllowed %s) finish", | |
+ debugPrefix, | |
+ attribute.name(), | |
+ tranToken.isCompletionAllowed())); | |
+ } | |
+ attribute.finish(manager, tranToken); | |
+ } | |
+ } | |
+ return object; | |
+ } | |
+ | |
+} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment