锁定老帖子 主题:如何在spring框架中解决多数据源的问题
精华帖 (8) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-05-14
spring和ejb都是利用JTA的能力来处理跨多个数据源的事务
ejb不仅没有什么优势可言,反而是灵活性不如spring |
|
返回顶楼 | |
发表时间: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的参数传值 |
|
返回顶楼 | |
发表时间:2007-05-14
切换datasource算是解决了,但是如何解决事务的问题呢?假如需要在一个事务中切换datasource,分别完成对数据库的操作?
|
|
返回顶楼 | |
发表时间:2007-05-14
如果需要跨库事务,按照我的方法,可以在HibernateTransactionManager上做文章
构造针对第二个SessionFactory的SessionHolder以及HibernateTransactionObject,甚至可以考虑构造一个HibernateTransactionObject的List,不过一般跨库都是跨两库 ,也用不着List 然后修改HibernateTransactionManager的doBegin doSuspend等调用方法,加入对第二个HibernateTransactionObject的操作 |
|
返回顶楼 | |
发表时间:2007-05-15
jasspier 写道 你这种做法,一次只能使用一只数据源,如果同时要对两个数据源做操作,你如何保证事务?
运用spring的事物处理机制是没有问题的 |
|
返回顶楼 | |
发表时间:2007-05-15
spring jta事物处理机制通过TransactionSynchronizer来做到这一点的
感觉里面的代码有点乱.., |
|
返回顶楼 | |
发表时间:2007-05-15
spring通过org.springframework.transaction.jta.JtaTransactionManager可以运用Jta进行跨数据库的事务管理
|
|
返回顶楼 | |
发表时间:2007-05-15
这真的是一个很有意思的问题,在我的项目中没有遇到,可以搭建一个环境实际测试一下,不过我坚信spring是可以解决的。
|
|
返回顶楼 | |
发表时间:2007-05-15
atianchen的解决方案也是一个不错的思路,可以看到,我们的方案都有一个共通的地方,就是运用线程直接从request中获得信息。但是,atianchen使用了多个sessionFactory,可实际上这多个sessionFactory在差别上只有dataSource,但却要装载多份值对象集,这恐怕在装载时间和资源耗费上都是一种不必要的浪费。atianchen可以再优化一下你的方案。
|
|
返回顶楼 | |
发表时间:2007-05-15
当然可以。。。
spring是个锤子 |
|
返回顶楼 | |