Browse Source

DATACMNS-720 - Improved disabling of default transactions.

When default transactions get disabled, we now still configure a TransactionInterceptor to make sure explicitly defined transactions are still applied. Previously the interceptor was not registered at all if default transactions were configured to be turned off and thus even explicitly declared transaction configuration was not considered.

Related tickets: DATACMNS-656.
1.10.x
Oliver Gierke 11 years ago
parent
commit
88523b8da3
  1. 8
      src/main/java/org/springframework/data/repository/core/support/TransactionalRepositoryFactoryBeanSupport.java
  2. 21
      src/main/java/org/springframework/data/repository/core/support/TransactionalRepositoryProxyPostProcessor.java
  3. 20
      src/test/java/org/springframework/data/repository/core/support/TransactionRepositoryFactoryBeanSupportUnitTests.java
  4. 7
      src/test/java/org/springframework/data/repository/core/support/TransactionRepositoryProxyPostProcessorUnitTests.java

8
src/main/java/org/springframework/data/repository/core/support/TransactionalRepositoryFactoryBeanSupport.java

@ -71,10 +71,7 @@ public abstract class TransactionalRepositoryFactoryBeanSupport<T extends Reposi @@ -71,10 +71,7 @@ public abstract class TransactionalRepositoryFactoryBeanSupport<T extends Reposi
RepositoryFactorySupport factory = doCreateRepositoryFactory();
factory.addRepositoryProxyPostProcessor(exceptionPostProcessor);
if (enableDefaultTransactions) {
factory.addRepositoryProxyPostProcessor(txPostProcessor);
}
factory.addRepositoryProxyPostProcessor(txPostProcessor);
return factory;
}
@ -95,7 +92,8 @@ public abstract class TransactionalRepositoryFactoryBeanSupport<T extends Reposi @@ -95,7 +92,8 @@ public abstract class TransactionalRepositoryFactoryBeanSupport<T extends Reposi
Assert.isInstanceOf(ListableBeanFactory.class, beanFactory);
ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory;
this.txPostProcessor = new TransactionalRepositoryProxyPostProcessor(listableBeanFactory, transactionManagerName);
this.txPostProcessor = new TransactionalRepositoryProxyPostProcessor(listableBeanFactory, transactionManagerName,
enableDefaultTransactions);
this.exceptionPostProcessor = new PersistenceExceptionTranslationRepositoryProxyPostProcessor(listableBeanFactory);
}
}

21
src/main/java/org/springframework/data/repository/core/support/TransactionalRepositoryProxyPostProcessor.java

@ -56,6 +56,7 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr @@ -56,6 +56,7 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr
private final BeanFactory beanFactory;
private final String transactionManagerName;
private final boolean enableDefaultTransactions;
/**
* Creates a new {@link TransactionalRepositoryProxyPostProcessor} using the given {@link ListableBeanFactory} and
@ -63,14 +64,17 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr @@ -63,14 +64,17 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr
*
* @param beanFactory must not be {@literal null}.
* @param transactionManagerName must not be {@literal null} or empty.
* @param enableDefaultTransaction
*/
public TransactionalRepositoryProxyPostProcessor(ListableBeanFactory beanFactory, String transactionManagerName) {
public TransactionalRepositoryProxyPostProcessor(ListableBeanFactory beanFactory, String transactionManagerName,
boolean enableDefaultTransaction) {
Assert.notNull(beanFactory);
Assert.notNull(transactionManagerName);
this.beanFactory = beanFactory;
this.transactionManagerName = transactionManagerName;
this.enableDefaultTransactions = enableDefaultTransaction;
}
/*
@ -81,6 +85,7 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr @@ -81,6 +85,7 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr
CustomAnnotationTransactionAttributeSource transactionAttributeSource = new CustomAnnotationTransactionAttributeSource();
transactionAttributeSource.setRepositoryInformation(repositoryInformation);
transactionAttributeSource.setEnableDefaultTransactions(enableDefaultTransactions);
TransactionInterceptor transactionInterceptor = new TransactionInterceptor(null, transactionAttributeSource);
transactionInterceptor.setTransactionManagerBeanName(transactionManagerName);
@ -259,6 +264,7 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr @@ -259,6 +264,7 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr
final Map<Object, TransactionAttribute> attributeCache = new ConcurrentHashMap<Object, TransactionAttribute>();
private RepositoryInformation repositoryInformation;
private boolean enableDefaultTransactions = true;
/**
* @param repositoryInformation the repositoryInformation to set
@ -267,6 +273,13 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr @@ -267,6 +273,13 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr
this.repositoryInformation = repositoryInformation;
}
/**
* @param enableDefaultTransactions the enableDefaultTransactions to set
*/
public void setEnableDefaultTransactions(boolean enableDefaultTransactions) {
this.enableDefaultTransactions = enableDefaultTransactions;
}
/**
* Determine the transaction attribute for this method invocation.
* <p>
@ -349,7 +362,7 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr @@ -349,7 +362,7 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr
// Last fallback is the class of the original method.
txAtt = findTransactionAttribute(method.getDeclaringClass());
if (txAtt != null) {
if (txAtt != null || !enableDefaultTransactions) {
return txAtt;
}
}
@ -368,6 +381,10 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr @@ -368,6 +381,10 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr
return txAtt;
}
if (!enableDefaultTransactions) {
return null;
}
// Fallback to implementation class transaction settings of nothing found
// return findTransactionAttribute(method);
Method targetClassMethod = repositoryInformation.getTargetClassMethod(method);

20
src/test/java/org/springframework/data/repository/core/support/TransactionRepositoryFactoryBeanSupportUnitTests.java

@ -18,6 +18,7 @@ package org.springframework.data.repository.core.support; @@ -18,6 +18,7 @@ package org.springframework.data.repository.core.support;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import static org.springframework.test.util.ReflectionTestUtils.*;
import org.junit.Test;
import org.springframework.aop.Advisor;
@ -38,7 +39,7 @@ public class TransactionRepositoryFactoryBeanSupportUnitTests { @@ -38,7 +39,7 @@ public class TransactionRepositoryFactoryBeanSupportUnitTests {
* @see DATACMNS-656
*/
@Test
public void doesNotRegisterTransactionalRepositoryProxyPostProcessorIfConfigured() {
public void disablesDefaultTransactionsIfConfigured() {
SampleTransactionalRepositoryFactoryBean factoryBean = new SampleTransactionalRepositoryFactoryBean();
factoryBean.setEnableDefaultTransactions(false);
@ -48,9 +49,22 @@ public class TransactionRepositoryFactoryBeanSupportUnitTests { @@ -48,9 +49,22 @@ public class TransactionRepositoryFactoryBeanSupportUnitTests {
CrudRepository<Object, Long> repository = factoryBean.getObject();
Advisor[] advisors = ((Advised) repository).getAdvisors();
boolean found = false;
assertThat(advisors.length, is(greaterThanOrEqualTo(2)));
assertThat(advisors[1].getAdvice(), is(not(instanceOf(TransactionInterceptor.class))));
for (Advisor advisor : advisors) {
if (advisor.getAdvice() instanceof TransactionInterceptor) {
found = true;
TransactionInterceptor interceptor = (TransactionInterceptor) advisor.getAdvice();
assertThat(getField(interceptor.getTransactionAttributeSource(), "enableDefaultTransactions"),
is((Object) false));
break;
}
}
assertThat(found, is(true));
}
@SuppressWarnings({ "unchecked", "rawtypes" })

7
src/test/java/org/springframework/data/repository/core/support/TransactionRepositoryProxyPostProcessorUnitTests.java

@ -63,18 +63,19 @@ public class TransactionRepositoryProxyPostProcessorUnitTests { @@ -63,18 +63,19 @@ public class TransactionRepositoryProxyPostProcessorUnitTests {
@Test(expected = IllegalArgumentException.class)
public void rejectsNullBeanFactory() throws Exception {
new TransactionalRepositoryProxyPostProcessor(null, "transactionManager");
new TransactionalRepositoryProxyPostProcessor(null, "transactionManager", true);
}
@Test(expected = IllegalArgumentException.class)
public void rejectsNullTxManagerName() throws Exception {
new TransactionalRepositoryProxyPostProcessor(beanFactory, null);
new TransactionalRepositoryProxyPostProcessor(beanFactory, null, true);
}
@Test
public void setsUpBasicInstance() throws Exception {
RepositoryProxyPostProcessor postProcessor = new TransactionalRepositoryProxyPostProcessor(beanFactory, "txManager");
RepositoryProxyPostProcessor postProcessor = new TransactionalRepositoryProxyPostProcessor(beanFactory, "txManager",
true);
postProcessor.postProcess(proxyFactory, repositoryInformation);
verify(proxyFactory).addAdvice(isA(TransactionInterceptor.class));

Loading…
Cancel
Save