Multiple transaction managers in spring and select one at runtime

穿精又带淫゛_ 提交于 2019-12-12 23:04:29

问题


For each client, I have separate databases but business logic and tables are same for each client. I want common service and dao layer for each client. In dao, I select datasource based on logged user client. In @Transactional, I have to pass bean id of transaction manager. How to make common service layer with @Transactional annotation.

Same question is here

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

  2. Choose between muliple transaction managers at runtime

but nobody reply


回答1:


If you want to create a database connection dynamically, then have a look at this SO post.

From the post linked : Basically in JDBC most of these properties are not configurable in the API like that, rather they depend on implementation. The way JDBC handles this is by allowing the connection URL to be different per vendor.

So what you do is register the driver so that the JDBC system can know what to do with the URL:

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

Then you form the URL:

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

And finally, use it to get a connection:

Connection c = DriverManager.getConnection(url);

In more sophisticated JDBC, you get involved with connection pools and the like, and application servers often have their own way of registering drivers in JNDI and you look up a DataSource from there, and call getConnection on it.

In terms of what properties MySQL supports, see here (The link is dead).

EDIT: One more thought, technically just having a line of code which does Class.forName("com.mysql.jdbc.Driver") should be enough, as the class should have its own static initializer which registers a version, but sometimes a JDBC driver doesn't, so if you aren't sure, there is little harm in registering a second one, it just creates a duplicate object in memeory.

I don't know if this will work, since I have not tested it, but you could try.

Now what you could do is, use the @Transactional annotation on top of the DAOs without specifying any values (That works). Now in your DAO classes, instead of injecting any DataSource bean, create your own dataSource dynamically as specified in the above link and then either inject that dependency at runtime, use getter setter methods, or just use the new keyword. I hope that'd do the trick.

NOTE: I have not tested it myself yet, so if this works, do let me know.




回答2:


You do not need to configure and switch between multiple transaction managers to accomplish your end goal. Instead use the Spring provided org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource mechanism.

Detailed examples can be found here :

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


来源:https://stackoverflow.com/questions/37116625/multiple-transaction-managers-in-spring-and-select-one-at-runtime

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!