如何在动态数据源的情况下使用spring transaction manager?

时间:2016-01-29 16:59:18

标签: java spring spring-mvc spring-jdbc jdbctemplate

我有一个使用Datasource Factory动态创建数据源的场景。因此,根据谁访问系统,DatasourceFacory(自定义数据源工厂)返回相应的datasource

现在,通过这种策略,我该如何维护Spring Transaction?使用@Transactional注释需要配置事务管理器的固定数据源。

我想继续在服务方法中使用@Transactional,而不必担心必须自己维护事务。

我认为我必须扩展一些spring类并在系统启动时注入数据源。

我在我的项目中使用Spring和JdbcTemplate。没有Hibernate。任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:1)

您必须使用AbstractRoutingDataSource将其与事务管理器链接,这种数据源允许您使用不同的数据源在运行时选择它们。

之后,spring会正确处理事务。您可以在Spring文档中检查这种数据源。

另一个选项是具有不同的transactionManagers。

答案 1 :(得分:0)

您可以使用不同的数据源创建多个事务管理器,然后在@Transactional注释中访问它们,如下所示:

 <bean id="txManager1" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource1"/>
    <qualifier value="txManager1"/>
 </bean>

将其作为:

访问
 @Transactional("txManager1")

类似地,

 <bean id="txManager2" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource2"/>
    <qualifier value="txManager2"/>
 </bean>

将其作为:

访问
 @Transactional("txManager2")

因为只能有一个注释驱动的TxManager,所以不要忘记删除它:

<tx:annotation-driven transaction-manager="transactionManager" />

答案 2 :(得分:0)

对于no-xml爱好者

@Bean(name = "mysqldatasource1")
public DataSource dataSource() {
    BasicDataSource dataSource = new BasicDataSource();
    dataSource.setDriverClassName(classname);
    dataSource.setUrl(url);
    dataSource.setUsername(usernmae);
    dataSource.setPassword(password);
    return dataSource;
}

@Bean(name = "mySqlJdbcTemplate1")
public JdbcTemplate jdbcTemplate() {
    JdbcTemplate jdbcTemplate = new JdbcTemplate();
    jdbcTemplate.setDataSource(dataSource());
    return jdbcTemplate;
}

@Bean(name="mysqlTransaction1") 
@Autowired
DataSourceTransactionManager tm1(@Qualifier ("mysqldatasource") DataSource datasource) {
    DataSourceTransactionManager txm  = new DataSourceTransactionManager(datasource);
    return txm;
}
@Bean(name = "mysqldatasource2")
public DataSource dataSource() {
    BasicDataSource dataSource = new BasicDataSource();
    dataSource.setDriverClassName(classname);
    dataSource.setUrl(url);
    dataSource.setUsername(usernmae);
    dataSource.setPassword(password);
    return dataSource;
}

@Bean(name = "mySqlJdbcTemplate2")
public JdbcTemplate jdbcTemplate() {
    JdbcTemplate jdbcTemplate = new JdbcTemplate();
    jdbcTemplate.setDataSource(dataSource());
    return jdbcTemplate;
}

@Bean(name="mysqlTransaction2") 
@Autowired
DataSourceTransactionManager tm1(@Qualifier ("mysqldatasource2") DataSource datasource) {
    DataSourceTransactionManager txm  = new DataSourceTransactionManager(datasource);
    return txm;
}