Axon多数据源配置:EntityManagerProvider事务异常咨询
解决方案:Axon多数据源下EntityManagerProvider的正确配置
核心问题分析
你之前的配置都会直接创建独立的EntityManager实例,这些实例未绑定到Spring管理的事务上下文,导致Axon操作事件存储时抛出TransactionRequiredException。正确思路是让Axon使用容器管理、与当前事务关联的EntityManager,而非手动创建独立实例。
正确配置步骤
1. 完善Axon专用数据源及关联组件配置
先确保已正确配置Axon专属的数据源、EntityManagerFactory和事务管理器:
@Bean(name = "axonDataSource") public DataSource axonDataSource() { HikariDataSource dataSource = new HikariDataSource(); dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/axon_db"); dataSource.setUsername("root"); dataSource.setPassword("password"); return dataSource; } @Bean(name = "axonEntityManagerFactory") public LocalContainerEntityManagerFactoryBean axonEntityManagerFactory( @Qualifier("axonDataSource") DataSource dataSource, EntityManagerFactoryBuilder builder) { return builder .dataSource(dataSource) .packages("org.axonframework.eventsourcing.eventstore.jpa") // 引入Axon JPA实体包 .persistenceUnit("axonPersistenceUnit") .build(); } @Bean(name = "axonPlatformTransactionManager") public PlatformTransactionManager axonPlatformTransactionManager( @Qualifier("axonEntityManagerFactory") EntityManagerFactory entityManagerFactory) { return new JpaTransactionManager(entityManagerFactory); }
2. 正确实现Axon的EntityManagerProvider
核心是让EntityManagerProvider返回当前事务上下文绑定的EntityManager,而非新创建的实例,可通过Spring的EntityManagerFactoryUtils实现:
import org.axonframework.common.transaction.TransactionManager; import org.axonframework.eventsourcing.eventstore.EventStore; import org.axonframework.eventsourcing.eventstore.jpa.JpaEventStore; import org.axonframework.serialization.Serializer; import org.axonframework.spring.config.SpringAxonAutoConfigurer; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.orm.jpa.EntityManagerFactoryUtils; import javax.persistence.EntityManagerFactory; // 排除Axon默认自动配置,避免覆盖自定义Bean @Configuration @EnableAutoConfiguration(exclude = {SpringAxonAutoConfigurer.class}) public class AxonCustomDataSourceConfig { @Bean(name = "axonTransactionManager") public TransactionManager axonTransactionManager( @Qualifier("axonPlatformTransactionManager") PlatformTransactionManager transactionManager) { return new SpringTransactionManager(transactionManager); } @Bean(name = "axonEntityManagerProvider") public EntityManagerProvider axonEntityManagerProvider( @Qualifier("axonEntityManagerFactory") EntityManagerFactory entityManagerFactory) { // 从当前事务上下文获取EntityManager,确保与业务事务绑定 return () -> EntityManagerFactoryUtils.getTransactionalEntityManager(entityManagerFactory); } // 手动配置Axon事件存储,指定使用自定义的EntityManagerProvider和事务管理器 @Bean public EventStore eventStore(EntityManagerProvider entityManagerProvider, TransactionManager transactionManager, Serializer serializer) { return JpaEventStore.builder() .entityManagerProvider(entityManagerProvider) .transactionManager(transactionManager) .serializer(serializer) .build(); } }
3. 关键注意事项
EntityManagerFactoryUtils.getTransactionalEntityManager()会自动获取与当前事务绑定的EntityManager,确保Axon操作在事务上下文内执行。- 所有Axon的JPA相关组件(如
JpaTokenStore、JpaSagaStore)都需指定使用自定义的axonEntityManagerProvider和axonTransactionManager,避免默认组件使用主数据源。 - 必须排除Axon默认的
SpringAxonAutoConfigurer,防止默认配置覆盖自定义Bean。
内容的提问来源于stack exchange,提问作者JJ36
相关产品推荐
相关产品推荐

