Spring中的多个事务管理器,并在运行时选择一个

时间:2016-05-09 13:07:00

标签: java spring transactions spring-transactions transactionmanager

对于每个客户端,我有单独的数据库,但每个客户端的业务逻辑和表都相同。我想为每个客户提供公共服务和dao层。在dao中,我根据记录的用户客户端选择数据源。在@Transactional中,我必须传递事务管理器的bean id。如何使用@Transactional注释创建公共服务层。

同样的问题在这里

  1. Multiple transaction managers - Selecting a one at runtime - Spring

  2. Choose between muliple transaction managers at runtime

  3. 但没有人回复

2 个答案:

答案 0 :(得分:0)

如果您想动态创建数据库连接,请查看this SO帖子。

  

来自帖子链接:基本上在JDBC中,大多数这些属性都不可配置   这样的API,而不是它们依赖于实现。 JDBC的方式   处理这是通过允许连接URL不同   的供应商。

     

所以你要做的就是注册驱动程序,以便JDBC系统知道   如何处理URL:

DriverManager.registerDriver((Driver)
Class.forName("com.mysql.jdbc.Driver").newInstance());
  

然后你形成   网址:

String url =
 "jdbc:mysql://[host][,failoverhost...][:port]/[database][?propertyName1][=propertyValue1][&propertyName2][=propertyValue2]"
  

最后,用它来建立连接:

Connection c = DriverManager.getConnection(url);
  

更多   复杂的JDBC,你参与连接池和   比如,应用程序服务器通常有自己的注册方式   JNDI中的驱动程序,你从那里查找一个DataSource,然后调用   getConnection就可以了。

     

就MySQL支持的属性而言,请参阅此处(链接已失效)。

     

编辑:还有一个想法,技术上只是有一行代码   Class.forName(" com.mysql.jdbc.Driver")应该足够了,因为   class应该有自己的静态初始化器,它注册一个   版本,但有时JDBC驱动程序没有,所以如果你不确定,   注册第二个没有什么害处,只是创建一个   在记忆中重复的对象。

     

我不知道这是否有效,因为我没有测试过,但是你   可以试试。

现在你可以做的是,在DAO之上使用@Transactional注释而不指定任何值(这是有效的)。现在在您的DAO类中,不是注入任何DataSource bean,而是按照上面的链接中的指定动态创建自己的dataSource,然后在运行时注入该依赖项,使用getter setter方法,或者只使用{{1} }关键字。我希望能做到这一点。

注意:我还没有自己测试过,所以如果有效,请告诉我。

答案 1 :(得分:0)

您无需在多个事务管理器之间进行配置和切换即可实现最终目标。而是使用Spring提供的org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource机制。

详细示例可在此处找到:

  1. https://spring.io/blog/2007/01/23/dynamic-datasource-routing/
  2. http://howtodoinjava.com/spring/spring-orm/spring-3-2-5-abstractroutingdatasource-example/