`
moonlight2010
  • 浏览: 19224 次
  • 性别: Icon_minigender_1
  • 来自: 青岛
社区版块
存档分类
最新评论

spring中配置多数据源

    博客分类:
  • java
阅读更多

最近项目中要增加数据源
所以自己在网上搜了下如何配置
首先看到这个文章,
地址:
http://www.oschina.net/question/54100_30592
感觉挺靠谱,就尝试在项目中配置了一下,
发现如下问题
1,按照文章所述是在dao层进行更改数据源,但是自己尝试了一下
发现不起作用。
原因是:spring的事物管理是在service层,也就是说在service层已经能够得到事物,
如果能够得到事物,那么数据源肯定已经确定了。所以也不能在service层进行更改数据源,也会不起作用
2,在action中进行更改数据源即执行

DataSourceContextHolder.setDataSourceType("2");


虽然会起作用,但是如果再访问其他的action的时候,有可能(为什么说有可能呢,
是因为你访问一次2次或者多次都没有发生异常,或者你访问一次就异常了。自己亲自测试的)会发现
后台报异常,分析异常才发现是因为这个action中走的数据源和自己期望的不对。
原因:
文章中写到通过更改threadLocal中的值,使其当前线程中的数据源发生变化,
threadLocal中存的是key-value类型map对象,
key应该是线程ID(这个我自己理解,如有不对请大家指出,谢谢。)
value就是数据源的标识值。1或者2.
有可能出现以下情况,
线程消失了,但是threadLocal中还有对应这个消失的线程id的value。
此时,一个新的线程产生,并且这个线程的id和消失的线程id相同,那么
在这个线程执行的时候,对应的数据源就是之前消失的线程设的值,
就是产生后台异常的原因。
threadLocal应该是jvm虚拟机进行垃圾回收进行清理,
但是线程消失和垃圾回收不同步,就会导致以上问题,
只需要把

public class DataSourceContextHolder {
	private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); // 线程本地环境   
	// 设置数据源类型   
	public static void setDataSourceType(String dataSourceType) {
		contextHolder.set(dataSourceType);
	}
	// 获取数据源类型     
	public static String getDataSourceType() {
		String ret =(String) contextHolder.get();
	  //自己新加 start
		contextHolder.set(DataSourceConst.BVS);
		//自己新加 end
		return ret;
	}
	// 清除数据源类型   
	public static void clearDataSourceType() {
		contextHolder.remove();
	}
	


这个类按照标注的新加一行代码即可,
取完线程的值,以后即刻把线程中的值设置成默认值。
这样就要求如果在一个action中如果执行2个service都不走默认数据源
就需要在每个service代码前设置

DataSourceContextHolder.setDataSourceType("2");


这样才能保证每次执行的SQL是22对应的数据源。
所以,如果要在spring配置多数据源,
只需要按照文章中
地址:
http://www.oschina.net/question/54100_30592配置,
并稍加修改就可以了。



 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics