Reduce PlatformTransactionManager lookups

Prior to this commit, cache operations mentioning a qualifier led to
a lookup for the same PlatformTransactionManager over and over again.
The same applied when a transactionManager bean name was specified on
the interceptor.

This commit adds a cache to store the reference of such transaction
managers. As a convenience, the default PlatformTransactionManager is
also initialized if it has not been through configuration.

Issue: SPR-11954
This commit is contained in:
Stephane Nicoll
2014-07-04 16:40:43 +02:00
parent 58955236ee
commit 4e257243f2
3 changed files with 158 additions and 27 deletions

View File

@@ -33,6 +33,7 @@ import org.springframework.util.StringUtils;
import java.lang.reflect.Method;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
/**
* Base class for transactional aspects, such as the {@link TransactionInterceptor}
@@ -76,6 +77,9 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
new NamedThreadLocal<TransactionInfo>("Current aspect-driven transaction");
private final ConcurrentHashMap<String, PlatformTransactionManager> transactionManagerCache =
new ConcurrentHashMap<String, PlatformTransactionManager>();
/**
* Subclasses can use this to return the current TransactionInfo.
* Only subclasses that cannot handle all operations in one method,
@@ -328,13 +332,27 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
}
String qualifier = txAttr.getQualifier();
if (StringUtils.hasLength(qualifier)) {
return BeanFactoryAnnotationUtils.qualifiedBeanOfType(this.beanFactory, PlatformTransactionManager.class, qualifier);
PlatformTransactionManager txManager = this.transactionManagerCache.get(qualifier);
if (txManager == null) {
txManager = BeanFactoryAnnotationUtils.qualifiedBeanOfType(
this.beanFactory, PlatformTransactionManager.class, qualifier);
this.transactionManagerCache.putIfAbsent(qualifier, txManager);
}
return txManager;
}
else if (this.transactionManagerBeanName != null) {
return this.beanFactory.getBean(this.transactionManagerBeanName, PlatformTransactionManager.class);
PlatformTransactionManager txManager = this.transactionManagerCache.get(this.transactionManagerBeanName);
if (txManager == null) {
txManager = this.beanFactory.getBean(
this.transactionManagerBeanName, PlatformTransactionManager.class);
this.transactionManagerCache.putIfAbsent(this.transactionManagerBeanName, txManager);
}
return txManager;
}
else {
return this.beanFactory.getBean(PlatformTransactionManager.class);
// Lookup the default transaction manager and store it for next call
this.transactionManager = this.beanFactory.getBean(PlatformTransactionManager.class);
return this.transactionManager;
}
}