如何在运行时创建(而不是切换)Datasource、JdbcTemplate 和 TransactionManager 实例?

问题描述 投票:0回答:1

我的 Spring Boot 应用程序在应用程序启动时不知道要连接到哪个数据库。它将在运行时接收 HTTP 请求正文中的输入(包括 dbtype、dbservername 等),并且它应该基于此输入连接到数据库实例。

对于我在 StackOverflow 上检查过的类似问题,人们建议了预先创建数据源实例,然后在运行时根据输入进行切换的方法。但是,我不想对不同数据库的配置进行硬编码。我希望应用程序在运行时创建 JdbcTemplate、Datasource 和 TransactionManager 实例。

这是我迄今为止在运行时创建 JdbcTemplate 和 Datasource 实例的尝试:

class DBConfig{
    private DataSource getMSSQLDatasource(String servername){
        // create MSSQL datasource using the servername
    }

    private DataSource getDB2Datasource(String servername){
        // create DB2 datasource using the servername
    }

    private JdbcTemplate setJdbcTemplate(String dbtype, String servername){
        return new JdbcTemplate(dbtype.equals("DB2") ? getDB2Datasource(servername) : getMSSQLDatasource(servername));
    }
}

所以我可以在运行时创建JdbcTemplate和Datasource。 但我还想使用 @Transactional 将一些查询作为事务执行,为此我需要一个 TransactionManager。 我不知道如何在运行时动态配置它。

所以我有两个问题:

  1. 有没有办法动态配置TransactionManager(就像我对JdbcTemplate所做的那样)?如果是这样怎么办?
  2. 有什么建议吗?
spring spring-boot jdbctemplate spring-transactions
1个回答
0
投票

我尝试了一种解决方法,到目前为止似乎效果很好。 任何建议都会非常有帮助

创建了一个实现 PlatformTransactionManager 的自定义类(DynamicTransactionManager):

@Component
class DynamicTransactionManager implements PlatformTransactionManager{
    private DataSource datasource;
    private DataSourceTransactionManager transactionManager;

    public void setDatasource(DataSource datasource){
        this.datasource = datasource;
        this.transactionManager = new DataSourceTransactionManager(datasource);
    }

    @Override
    public TransactionStatus getTransaction (TransactionDefinition definition) throws TransactionException { 
        return transactionManager.getTransaction (definition);
    }

    @Override
    public void commit (TransactionStatus status) throws TransactionException {
        transactionManager.commit(status);
    }

    @Override
    public void rollback(TransactionStatus status) throws TransactionException {
        transactionManager.rollback(status);
    }
}

现在在 DBConfig 类中,创建 JdbcTemplate 时,访问 DynamicTransactionManager 的 bean 并动态设置 DataSource,如下所示:

class DBConfig{
    private DataSource getMSSQLDatasource(String servername){
        // create MSSQL datasource using the servername
    }

    private DataSource getDB2Datasource(String servername){
        // create DB2 datasource using the servername
    }

    private JdbcTemplate setJdbcTemplate(String dbtype, String servername){
        DataSource datasource = dbtype.equals("DB2") ? getDB2Datasource(servername) : getMSSQLDatasource(servername);
        
        // CONFIGURE TRANSACTION MANAGER
        DynamicTransactionManager transactionManager = applicationContext.getBean(DynamicTransactionManager.class); 
        transactionManager.setDataSource(datasource);
        
        return new JdbcTemplate(datasource);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.