You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 11:17:49