论坛首页 Java企业应用论坛

如何在spring框架中解决多数据源的问题

浏览 109933 次
精华帖 (8) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-05-14  
spring和ejb都是利用JTA的能力来处理跨多个数据源的事务
ejb不仅没有什么优势可言,反而是灵活性不如spring
0 请登录后投票
   发表时间:2007-05-14  
最近我也在开发这样一个系统,不过我没有用fangang的方法,而是同时初始化多个sessionFactory,因为系统中经常有跨库操作,所以同时初始化并维持多个sessionFactory对于跨库操作方便一些,然后重写了spring的HibernateDaoSupport,
具体实现步骤如下:
多sessionFactory的配置就不写了
然后我写了一个HibernateSupport提供工厂访问支持,HibernateSupport通过解析一个XML获取环境的sessionFactory
	<hibernatesupport>
		<item id="mit" bean="mitSessionFactory"/>
		<item id="test1" bean="test1SessionFactory"/>
	</hibernatesupport>

HibernateSupport通过ThreadLocal保存request请求下的SessionFactory
private static ThreadLocal curfactory;
当一个请求进来时候,我写了一个Filter会根据request请求信息设置当前的sessionFactory
 
  ApplicationContext applicationContext = 
	WebApplicationContextUtils
		            .getWebApplicationContext(context);
	curfactory.set((SessionFactory)applicationContext
						.getBean((String)factorybeanset.get(id)));

id就是刚才配置里面的mit或则test1

然后,写一个方法,让其他程序可以获取当前的sessionFactory
public static SessionFactory getCurrentFactory()
{
  return (SessionFactory)curfactory.get();
}

然后就是重写,需要重写spring关于Hibernate3支持的四个类
HibernateAccessor,HibernateDaoSupport,HibernateTemplate,HibernateTransactionManager
其实主要是修改HibernateAccessor和HibernateTransactionManager的sessionFactory获取方式,由于HibernateDaoSupport->HibernateTemplate->HibernateAccessor,所以重写HibernateAccessor就要重写HibernateDaoSupport和HibernateTemplate
首先删除掉HibernateAccessor和HibernateTransactionManager关于sessionFactory的变量和setSessionFactory方法,修改getSessionFactory()方法
	public SessionFactory getSessionFactory()
	{
		return HibernateSupport.getCurrentFactory();
	}

然后打包,OK
然后修改spring配置文件
首先是事务管理
<bean id="transactionManager" 
  class="org.springframework.orm.hibernate3.CHibernateTransactionManager"/>

CHibernateTransactionManager就是我重写的Hibernate事务管理类
我的Dao类也从我重写的CHibernateDaoSupport继承
都不需要设置sessionFactory的参数传值
0 请登录后投票
   发表时间:2007-05-14  
切换datasource算是解决了,但是如何解决事务的问题呢?假如需要在一个事务中切换datasource,分别完成对数据库的操作?
0 请登录后投票
   发表时间:2007-05-14  
如果需要跨库事务,按照我的方法,可以在HibernateTransactionManager上做文章
构造针对第二个SessionFactory的SessionHolder以及HibernateTransactionObject,甚至可以考虑构造一个HibernateTransactionObject的List,不过一般跨库都是跨两库 ,也用不着List
然后修改HibernateTransactionManager的doBegin doSuspend等调用方法,加入对第二个HibernateTransactionObject的操作
0 请登录后投票
   发表时间:2007-05-15  
jasspier 写道
你这种做法,一次只能使用一只数据源,如果同时要对两个数据源做操作,你如何保证事务?

运用spring的事物处理机制是没有问题的
0 请登录后投票
   发表时间:2007-05-15  
spring jta事物处理机制通过TransactionSynchronizer来做到这一点的
感觉里面的代码有点乱..,
0 请登录后投票
   发表时间:2007-05-15  
spring通过org.springframework.transaction.jta.JtaTransactionManager可以运用Jta进行跨数据库的事务管理
0 请登录后投票
   发表时间:2007-05-15  
这真的是一个很有意思的问题,在我的项目中没有遇到,可以搭建一个环境实际测试一下,不过我坚信spring是可以解决的。
0 请登录后投票
   发表时间:2007-05-15  
atianchen的解决方案也是一个不错的思路,可以看到,我们的方案都有一个共通的地方,就是运用线程直接从request中获得信息。但是,atianchen使用了多个sessionFactory,可实际上这多个sessionFactory在差别上只有dataSource,但却要装载多份值对象集,这恐怕在装载时间和资源耗费上都是一种不必要的浪费。atianchen可以再优化一下你的方案。
0 请登录后投票
   发表时间:2007-05-15  
当然可以。。。
spring是个锤子
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics