两个dataSources
1 | <!-- 配置dbcp数据源 - dev --> |
MultiDataSource
需要自己实现数据源路由, 继承AbstractRoutingDataSource,覆写determineCurrentLookupKey方法即可。
1 | package com.shhxzq.fin.ehelper.biz.util; |
其中DataSource是个枚举:
1 | package com.shhxzq.fin.ehelper.model.constants; |
sqlSessionFactory
1 | <!-- 创建SqlSessionFactory,同时指定数据源 --> |
sqlSession
1 | <!-- 配置SQLSession模板 --> |
transactionManager
1 | <!-- 使用JDBC事务 --> |
transactionAdvice
1 | <!-- AOP配置事物 --> |
transactionPointcut
1 | <!-- 配置AOP切面 --> |
方案一
原本我是想在spring初始化bean的时候就指定数据源,这样的话事务就不会和数据源打架,我想到的方案是,给不同的包指定不同的数据源,但是这样会带来一个问题,就是会冗余代码。
比如dev环境和uat环境的service分别放在dev和uat包下,再分别给dev包河uat包指定dev的数据源和uat的数据源。
引发的问题:dev和uat业务逻辑一样,仅数据源不一样,但是却有两份代码!冗余还是小事,以后维护才是大事,所以此方案果断排除。
方案二
在调用方法的时候传入一个参数,指定调用哪个数据源,这样代码就没冗余的地方了,但是会带来一个问题。
就是需要修改老代码,在参数中增加一个参数,然后在方法中指定数据源,在方法中指定数据源可以使用注解和切面完成,但不可避面的还是要增加一个参数。
如果不增加一个参数,而是在注解中加参数呢?我也这么想过,但是这样的话,这个方法就只能使用固定的数据源了,达不到动态的效果。
进一步分析,如果在注解中加参数,另外再多写一个方法指定为另一个数据源呢?显然是不可取的,方法冗余,维护困难,如果再次增加数据源还得再加一个方法。
所以,最后我还是选择了使用【传参+注解】的方案,没办法,要想动态切换数据源,你总的告诉方法你要用哪个数据源吧,怎么告诉他?传参是最好途径了,并且扩展性强。下面是我具体实现代码。
DataSourceSwitch
1 | package com.shhxzq.fin.ehelper.model.annotation; |
DataSourceAop
1 | package com.shhxzq.fin.ehelper.biz.aop; |
BeCommandServiceImpl
1 | package com.shhxzq.fin.ehelper.biz.service.impl; |
问题
另外我还遇到了一个问题,那就是事务和多数据源打架了,我的解决方案是把它们两个分开。但也不是太好,先这样吧,以后再研究。