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

Spring 6(非Boot)如何编程配置DataSource与事务管理器

解决方案:非Spring Boot环境下配置Spring 6事务管理器

你推测的问题根源完全正确——仅添加@EnableTransactionManagement只是启用了事务注解的支持,但Spring需要一个PlatformTransactionManager类型的Bean来处理实际的事务逻辑,非Spring Boot环境下不会自动创建这个Bean,导致@Transactional注解无法生效。

以下是两种适配你场景的配置方案,任选其一即可:


方案1:基于JPA EntityManager的配置(推荐)

这种方式贴合你当前使用EntityManager的代码习惯,通过LocalContainerEntityManagerFactoryBean管理JPA实体管理器,搭配JpaTransactionManager实现事务管理:

@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = "com.cypherf") // 确保Spring能扫描到你的Repository
public class PersistenceConfig {

    // 配置JPA实体管理器工厂
    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
        // 指定Hibernate作为JPA实现
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setShowSql(true);
        vendorAdapter.setFormatSql(true);

        emf.setJpaVendorAdapter(vendorAdapter);
        emf.setPackagesToScan("com.cypherf.model"); // 实体类所在包
        emf.setJpaProperties(hibernateProperties()); // 加载Hibernate配置属性
        emf.setDataSource(dataSource()); // 配置数据源

        return emf;
    }

    // 配置数据库数据源
    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("org.h2.Driver");
        dataSource.setUrl("jdbc:h2:./spring");
        dataSource.setUsername("sa");
        dataSource.setPassword("");
        return dataSource;
    }

    // 封装Hibernate核心配置
    private Properties hibernateProperties() {
        Properties props = new Properties();
        props.put("hibernate.dialect", "org.hibernate.community.dialect.H2LegacyDialect");
        props.put("hibernate.hbm2ddl.auto", "create-drop");
        props.put("hibernate.show_sql", "true");
        props.put("hibernate.format_sql", "true");
        return props;
    }

    // 关键:配置事务管理器
    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);
        return transactionManager;
    }
}

方案2:基于Hibernate SessionFactory的配置

如果你更倾向于保留原生Hibernate的SessionFactory配置,可以用这种方式,搭配HibernateTransactionManager:

@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = "com.cypherf")
public class PersistenceConfig {

    // 配置Hibernate SessionFactory
    @Bean
    public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        sessionFactory.setPackagesToScan("com.cypherf.model");
        sessionFactory.setHibernateProperties(hibernateProperties());
        return sessionFactory;
    }

    // 配置数据源(同方案1)
    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("org.h2.Driver");
        dataSource.setUrl("jdbc:h2:./spring");
        dataSource.setUsername("sa");
        dataSource.setPassword("");
        return dataSource;
    }

    // Hibernate配置属性(同方案1)
    private Properties hibernateProperties() {
        Properties props = new Properties();
        props.put("hibernate.dialect", "org.hibernate.community.dialect.H2LegacyDialect");
        props.put("hibernate.hbm2ddl.auto", "create-drop");
        props.put("hibernate.show_sql", "true");
        props.put("hibernate.format_sql", "true");
        return props;
    }

    // 配置Hibernate事务管理器
    @Bean
    public PlatformTransactionManager transactionManager(SessionFactory sessionFactory) {
        HibernateTransactionManager transactionManager = new HibernateTransactionManager();
        transactionManager.setSessionFactory(sessionFactory);
        return transactionManager;
    }

    // 可选:如果仍需使用EntityManager,从SessionFactory转换
    @Bean
    public EntityManagerFactory entityManagerFactory(SessionFactory sessionFactory) {
        return sessionFactory.unwrap(EntityManagerFactory.class);
    }
}

配置后的注意事项

  1. 确保你的MessageRepository是通过Spring容器获取的实例(比如用@Autowired注入到服务类),而非手动new创建,否则Spring的AOP代理无法生效,@Transactional注解不会起作用。
  2. @Transactional注解可以放在类上(所有方法生效),也可以单独标注在save方法上,按需调整即可。

内容的提问来源于stack exchange,提问作者Gaetan L.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 11:59:56