首页 > 解决方案 > 当 DataSources /JdbcTemplates 不由 Spring 管理时使用 Spring Boots @Transactional

问题描述

因此,在 My Spring 应用程序中,我们有多个数据源(每个都是具有不同用户名密码的不同数据库),它们在运行时构造为 HikariDataSource,它们不受 Spring 容器管理。我们使用不受 Spring 容器管理的 JDBC 模板。我的理解是@Transactional 在这种情况下不会开箱即用(即使我在服务层中使用@Transactional 调用的方法是Spring 托管bean)

我如何能

1- 当我的 HikariDataSource 不是由 spring 管理时,使 @Transactional 工作

2- 使 @Transactional 与不受 spring 管理的 JdbcTemplate 一起工作

我不需要跨多个数据源维护单个事务。

在运行时构建的数据源非常动态,可能有 50 个,可能有 100 个。我不能硬编码“这是 DataSource 1 的事务管理器”等

标签: springspring-boot

解决方案


您可以创建 2 个存储库配置并创建单独的事务管理器。

现在您可以告诉@Transactional (name ="xxxTransactionManager),因此Spring 知道要使用哪个事务管理器。

XXXRepositoryConfig {

@Bean
    fun xxxEntityManagerFactory(
        factoryBuilder: EntityManagerFactoryBuilder,
        @Qualifier("xxxDataSource") xxxDataSource: DataSource
    ): LocalContainerEntityManagerFactoryBean {
        return factoryBuilder
            .dataSource(xxxDataSource)
            .packages("com.xxx.entitites")
            .properties(mapOf("hibernate.default_schema" to "xxxSchema"))
            .build()
    }

    @Bean
    fun xxxTransactionManager(@Qualifier("xxxEntityManagerFactory") xxxEntityManagerFactory: EntityManagerFactory): PlatformTransactionManager {
        val transactionManager = JpaTransactionManager()
        transactionManager.entityManagerFactory = xxxEntityManagerFactory
        transactionManager.entityManagerFactory = xxxEntityManagerFactory
        return transactionManager
    }
}

YYYRepositoryConfig {

@Bean
    fun yyyEntityManagerFactory(
        factoryBuilder: EntityManagerFactoryBuilder,
        @Qualifier("yyyDataSource") yyyDataSource: DataSource
    ): LocalContainerEntityManagerFactoryBean {
        return factoryBuilder
            .dataSource(yyyDataSource)
            .packages("com.yyy.entitites")
            .properties(mapOf("hibernate.default_schema" to "yyySchema"))
            .build()
    }

    @Bean
    fun yyyTransactionManager(@Qualifier("yyyEntityManagerFactory") yyyEntityManagerFactory: EntityManagerFactory): PlatformTransactionManager {
        val transactionManager = JpaTransactionManager()
        transactionManager.entityManagerFactory = yyyEntityManagerFactory
        return transactionManager
    }
}

注意:sudo 代码是用 kotlin 编写的


推荐阅读