Dynamic Selection of TransactionManager Spring Boot

Multi tool use
Multi tool use


Dynamic Selection of TransactionManager Spring Boot



I am converting my existing Spring Application to a Spring Boot Application. In my existing application, we have the need to connect to multiple databases and we had achieved this by having multiple data sources defined and fetching the corresponding bean based on the condition. The transaction manager were also selected using a custom implementation of TransactionInterceptor.


@Override
public TransactionAttributeSource getTransactionAttributeSource() {
final TransactionAttributeSource origTxAttrSource = super.getTransactionAttributeSource();
return new TransactionAttributeSource() {

@Override
public TransactionAttribute getTransactionAttribute(final Method method, final Class<?> targetClass) {
TransactionAttribute txAttr = origTxAttrSource.getTransactionAttribute(method, targetClass);
String database = (String) ThreadContext.get("database");
if (database != null && StringUtils.isNotBlank(database)) {
if (txAttr instanceof DefaultTransactionAttribute) {
((DefaultTransactionAttribute) txAttr).setQualifier("txManager" + database);
}
}
return txAttr;
}
};
}



Through a BeanFactoryPostProcessor we were including this interceptor


BeanFactoryPostProcessor


@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String names = beanFactory.getBeanNamesForType(TransactionInterceptor.class);
for (String name : names) {
BeanDefinition bd = beanFactory.getBeanDefinition(name);
bd.setBeanClassName(MyTransactionInterceptor.class.getName());

}
}



This worked perfectly fine in Spring 4.X.



Now that we are moving towards Spring Boot, I am trying to convert the same approach. I can see that the bean factory is getting called but I don't find calls happening to the Custom Interceptor class. This results in my @Transactional to fail as there are more than one qualifying bean.


@Transactional



Am I missing something with regards to the Spring Boot Configuration?



(This approach of dynamic transaction management was through a reference blog http://blog.tirasa.net/dynamic-springs--at-transactional.html)





Add the exception and you might want do exclude the EnableTransactionManagementConfiguration from kicking in as that enables transaction management. Although it should already backoff if you yourself add @EnableTransactionManagement.
– M. Deinum
Jun 28 at 17:10


EnableTransactionManagementConfiguration


@EnableTransactionManagement





@EnableTransactionManagement annotation is not present. Basically, I have two transaction managers define (one for PostGre and another for MySQL). The exception I get is when the Transaction Proxy is being executed that there were two qualifying beans. Will post the stacktrace shortly.
– Aravind
Jun 29 at 0:55





org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.transaction.PlatformTransactionManager' available: expected single matching bean but found 2: postgreTxManager,mysqlTxManager at (so on until ) org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
– Aravind
Jun 29 at 2:29





1 Answer
1



The final answer turned out to be setting the factory classes and the factory bean name to null which resulted in the transaction interceptor being invoked. I am yet to figure out how this affects the interceptor call as with the values in these fields (they point to the ProxyTransaction classes as transactionInterceptor bean is created by it).



The final code was of the form -



TransactionInterceptor Class


@Component
public class TransactionInterceptorReplacer implements BeanFactoryPostProcessor {

@Override
public void postProcessBeanFactory(final ConfigurableListableBeanFactory factory) throws BeansException {
String names = factory.getBeanNamesForType(TransactionInterceptor.class);
for (String name : names) {
BeanDefinition bd = factory.getBeanDefinition(name);
bd.setBeanClassName(MyTransactionInterceptor.class.getName());
bd.setFactoryBeanName(null);
bd.setFactoryMethodName(null);
}
}
}






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

PHCRl jfQJjFAJQ3FK,yV HHwrAriW
CIWQZfen,lp,8DpVjrFFBQ,0mMg,I njDcIzU0AZW,tk9ApYdq3Znt6n,wCBqjBs3D0di,0C,McPW4nVjCU4 Huh

Popular posts from this blog

PHP contact form sending but not receiving emails

Do graphics cards have individual ID by which single devices can be distinguished?

Create weekly swift ios local notifications