Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom platform transaction manager in spring

I'm trying to implement custom transactional cache in a spring boot application. I've created my own implementation of AbstractPlatformTransactionManager and some unit tests, which show transactions are working as expected. However the real application ignores my transaction manager - it`s methods are never called. What I'm doing wrong? Thank you.

Transaction manager implementation:

@Component
public class CacheTransactionManager extends AbstractPlatformTransactionManager{
    @Override
    protected Object doGetTransaction() throws TransactionException {
    ...
    }
...
}

Cache transaction configuration:

@Configuration
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
public class CacheTransactionConfiguration {

    @Bean(name = "cacheTransactionManager")
    public PlatformTransactionManager cacheTransactionManager() {
        return new CacheTransactionManager();
    }  

}

Custom transactional annotation (I've tried also without this, but no difference):

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional(value = "cacheTransactionManager", rollbackFor = Exception.class)
public @interface CacheTransactional {

}

Cache service:

@Component
public class CacheService {
    @CacheTransactional
    public void add(Object o){
        ...
    }
}

Working JUnit test:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestApplication.class)
@Configuration
@EntityScan(...)
@IntegrationTest
@TransactionConfiguration(defaultRollback = false)
public class CacheTransactionManagerTest {
    @Autowired
    private CacheService cacheService;

    @Test
    @CacheTransactional
    public void transactionTest(){
        cacheService.add(new Object());
    }
}

Not working wicket application main class (ignores cacheTransactionManager):

@Configuration("MyApplication")
@EnableAutoConfiguration
@EntityScan(...)
@EnableJpaRepositories(...)
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
@ComponentScan(...)
@ImportResource({...})
public class MyApplication extends AuthenticatedWebApplication {
...
}

My env: Java 8, Spring Boot 1.2.1, Spring 4.1.4, Spring data JPA 1.7.2, Hibernate 4.3.7, Apache Tomcat 8.0.15, Wicket 6.17.0

like image 413
Michal Avatar asked Feb 17 '15 14:02

Michal


1 Answers

I found out some new facts:

  • when I remove AdviceMode.ASPECTJ from @EnableTransactionManagement on CacheTransactionConfiguration, transactions begin to work, but propagation of transaction is ignored - nested call from one @CacheTransactional method to another @CacheTransactional methods always creates new transaction. Same behavior in JUnit test and real application.

  • when AdviceMode.ASPECTJ is on CacheTransactionConfiguration setted, but I remove @CacheTransactional annotation from junit test, transaction stops working also in juint (in test body is a @CacheTransaction method called, so there should be a transaction created).

  • application log contains this entry: o.s.c.a.ConfigurationClassBeanDefinitionReader isOverriddenByExistingDefinition:290 - Skipping bean definition for [BeanMethod:name=cacheTransactionManager,declaringClass=x.y.z.CacheTransactionConfiguration]: a definition for bean 'cacheTransactionManager' already exists. This top-level bean definition is considered as an override.

So I can get this working, but without propagation...

like image 176
Michal Avatar answered Oct 01 '22 02:10

Michal