diff --git a/source/java/org/alfresco/repo/transaction/RetryingTransactionInterceptor.java b/source/java/org/alfresco/repo/transaction/RetryingTransactionInterceptor.java index 0495c62ae9..109ecf2098 100755 --- a/source/java/org/alfresco/repo/transaction/RetryingTransactionInterceptor.java +++ b/source/java/org/alfresco/repo/transaction/RetryingTransactionInterceptor.java @@ -1,21 +1,21 @@ /* -* Copyright (C) 2005-2010 Alfresco Software Limited. -* -* This file is part of Alfresco -* -* Alfresco is free software: you can redistribute it and/or modify -* it under the terms of the GNU Lesser General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alfresco is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public License -* along with Alfresco. If not, see . -*/ + * Copyright (C) 2005-2011 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ package org.alfresco.repo.transaction; import java.lang.reflect.Method; @@ -25,6 +25,7 @@ import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransacti import org.alfresco.service.transaction.TransactionService; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; +import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.interceptor.TransactionAspectSupport; import org.springframework.transaction.interceptor.TransactionAttribute; @@ -40,32 +41,73 @@ public class RetryingTransactionInterceptor extends TransactionAspectSupport imp this.transactionService = transactionService; } - public Object invoke(final MethodInvocation target) throws Throwable + public Object invoke(final MethodInvocation invocation) throws Throwable { - if ((null != target) && (null != target.getThis()) && (null != target.getMethod())) + if ((null != invocation) && (null != invocation.getThis()) && (null != invocation.getMethod())) { - final Method method = target.getMethod(); - final TransactionAttribute txnAttr = getTransactionAttributeSource().getTransactionAttribute(method, target.getThis().getClass()); - if (null != txnAttr && txnAttr.getPropagationBehavior() != TransactionAttribute.PROPAGATION_SUPPORTS) + final Method method = invocation.getMethod(); + final TransactionAttribute txnAttr = getTransactionAttributeSource().getTransactionAttribute( + method, invocation.getThis().getClass()); + final PlatformTransactionManager tm = determineTransactionManager(txnAttr); + @SuppressWarnings("deprecation") + final String joinpointIdentification = methodIdentification(invocation.getMethod()); + final int propagationBehaviour = txnAttr.getPropagationBehavior(); + try { - RetryingTransactionCallback txnCallback = new RetryingTransactionCallback() + if (null != txnAttr && propagationBehaviour != TransactionAttribute.PROPAGATION_SUPPORTS) { - @Override - public Object execute() throws Throwable - { - return target.proceed(); - } - }; - return transactionService.getRetryingTransactionHelper().doInTransaction( - txnCallback, - txnAttr.isReadOnly(), - (TransactionAttribute.PROPAGATION_REQUIRES_NEW == txnAttr.getPropagationBehavior())); + return transactionService.getRetryingTransactionHelper().doInTransaction( + new RetryingTransactionCallback() + { + public Object execute() + { + TransactionInfo txInfo = createTransactionIfNecessary(tm, TransactionAttribute.PROPAGATION_REQUIRES_NEW == txnAttr + .getPropagationBehavior() ? null : txnAttr, + joinpointIdentification); + try + { + return invocation.proceed(); + } + catch (RuntimeException e) + { + completeTransactionAfterThrowing(txInfo, e); + throw e; + } + catch (Throwable e) + { + // Wrap non-runtime exceptions so that they can be preserved + completeTransactionAfterThrowing(txInfo, e); + throw new WrapperException(e); + } + finally + { + cleanupTransactionInfo(txInfo); + } + } + }, + txnAttr.isReadOnly(), + (TransactionAttribute.PROPAGATION_REQUIRES_NEW == propagationBehaviour)); + } + else + { + return invocation.proceed(); + } } - else + catch (WrapperException e) { - return target.proceed(); + throw e.getCause(); } } - throw new AlfrescoRuntimeException("Invalid or undefined MethodInvocation instance: " + target.getMethod()); + throw new AlfrescoRuntimeException("Invalid undefined MethodInvocation instance"); + } + + public static class WrapperException extends RuntimeException + { + private static final long serialVersionUID = 1L; + + public WrapperException(Throwable cause) + { + super(cause); + } } }