精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-04-15
1、使用场景: 以自己为例,现有一个后台管理系统管理着游戏数据。以前是一个后台地址对应一个后台管理一个游戏后台,现在改进为一个后台管理多个游戏数据。在登录或者其他地方切换下就可以查询数据。
2、步骤分为:多数据源配置和动态切换配置和事务+OpenSessionInViewFilter配置
先不考虑动态切换配置,一个datasource对应一个sessionFactory对应一个hibernateTemplate对应一个transactionManager对应一个OpenSessionInViewFilter
在多数据源模式下有多个sessionFactory,所以配置hibernateTemplate,transactionManager,OpenSessionInViewFilter的时候要指定sessionFactory!
<filter> <filter-name>OpenSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> <init-param> <param-name>sessionFactoryBeanName</param-name> <param-value>sessionFactory1</param-value> </init-param> </filter> <filter-mapping> <filter-name>OpenSessionInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping><filter> <filter-name>OpenSessionInViewFilter4</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> <init-param> <param-name>sessionFactoryBeanName</param-name> <param-value>sessionFactory4</param-value> </init-param> </filter> <filter-mapping> <filter-name>OpenSessionInViewFilter4</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <bean id="transactionManager4" class="org.springframework.orm.hibernate3.HibernateTransactionManager" autowire="byName"> <property name="sessionFactory" ref="sessionFactory4"></property> </bean>
其中transactionManager有一个问题,就是配置aop的时候要注意2个transactionManager不重叠。
3、在dao中注入不同的sessionfactory/hibernateTemplate 操作各自所属数据源数据
HibernateTemplate hibernateTemplate; @Resource(name = "hibernateTemplate4") public void setHibernateTemplate(HibernateTemplate hibernateTemplate) { this.hibernateTemplate = hibernateTemplate; }HibernateTemplate hibernateTemplate; @Resource(name = "hibernateTemplate1") public void setHibernateTemplate(HibernateTemplate hibernateTemplate) { this.hibernateTemplate = hibernateTemplate; } 4、动态切换数据源(用来切换服务器)
public class DynamicDataSource extends AbstractRoutingDataSource { private static final Logger log = Logger.getLogger(DynamicDataSource.class); @Override protected Object determineCurrentLookupKey() { String i= CustomerContextHolder.getCustomerType(); return i; } }<bean id="dataSource00" class="com.xxx.util.DynamicDataSource"> <property name="targetDataSources"> <map key-type="java.lang.String"> <entry key="2" value-ref="dataSource2" /> <entry key="1" value-ref="dataSource1" /> </map> </property> <property name="defaultTargetDataSource" ref="dataSource1" /> </bean> 动态切换很简单,datasource配置改为AbstractRoutingDataSource实现类指定一个defaultTargetDataSource和targetDataSources 在需要切换的地方
public class CustomerContextHolder { private static final ThreadLocal contextHolder = new ThreadLocal(); public static void setCustomerType(String customerType) { contextHolder.set(customerType); } public static String getCustomerType() { return (String) contextHolder.get(); } public static void clearCustomerType() { contextHolder.remove(); } }CustomerContextHolder.setCustomerType("2");//切换key为2的数据源 User uu = userService.get(User.class, "id = ?", 3l); 就这样查询出来的就是第二个数据源的数据了
不出意外的话,是可以看到效果的。如果出现了事务问题就要查找下是否sessionfactory和aop配置正确。如果你把一个service类在aop中配置2次会出现错误的。 多数据源:管理系统数据源+游戏数据源 动态切换:游戏数据各服务器之间切换。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-04-15
谢谢:http://guoweisong.iteye.com/blog/751482
虽然他也是转载的,虽然找不到原博主,虽然上面描述的事务问题没有遇到 但是描述的很详细,分析步骤很清晰! |
|
返回顶楼 | |
发表时间:2011-04-15
最后修改:2011-04-15
我发现一个奇怪的问题,就是动态切换的时候ThreadLocal 居然没有保持set进去的值
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); ------------------------- 这个地方不要用ThreadLocal 。。。 设置一个static变量来保存key值就行了。 |
|
返回顶楼 | |
发表时间:2011-04-16
感觉这种设计方式不是很好吧,
|
|
返回顶楼 | |
发表时间:2011-04-16
最后修改:2011-04-16
大型的项目当中是不能切换数据源
不然会存在数据唯一性 的问题 |
|
返回顶楼 | |
发表时间:2011-04-16
LZ有没想过用JTA做?
用JOTM配合JTA,配置多个数据源,多个seesionfactory 还能确保事务一致呢 |
|
返回顶楼 | |
发表时间:2011-04-17
fairplay 写道 LZ有没想过用JTA做?
用JOTM配合JTA,配置多个数据源,多个seesionfactory 还能确保事务一致呢 jta没用过。 上面说的大概对于简单的系统没什么问题 数据唯一性 是什么问题?。不切换数据源怎么看多个数据库的数据? 还有我这个系统2个数据源的数据没有关联的。 |
|
返回顶楼 | |
发表时间:2011-04-20
这种多数据源的还是用jta来得方便,JOTM就足够了,或者用一些容器的实现,比如websphere,不明白的是为啥要切换数据源,切换seesionfactory 不可以吗,可以仿照spring的多数据源实现一下就可以了,这个地方不太明白
|
|
返回顶楼 | |
发表时间:2011-04-20
371937605 写道 这种多数据源的还是用jta来得方便,JOTM就足够了,或者用一些容器的实现,比如websphere,不明白的是为啥要切换数据源,切换seesionfactory 不可以吗,可以仿照spring的多数据源实现一下就可以了,这个地方不太明白
你没明白使用场景,多数据源归多数据源 动态切换归动态切换。 |
|
返回顶楼 | |
发表时间:2011-04-20
ak121077313 写道 371937605 写道 这种多数据源的还是用jta来得方便,JOTM就足够了,或者用一些容器的实现,比如websphere,不明白的是为啥要切换数据源,切换seesionfactory 不可以吗,可以仿照spring的多数据源实现一下就可以了,这个地方不太明白
你没明白使用场景,多数据源归多数据源 动态切换归动态切换。 每个seesionfactory 榜定一个数据源,多个seesionfactory 不就是多数据源了吗? 动态的切换seesionfactory 不就是切换数据源了吗,可能我真没理解,哈哈 |
|
返回顶楼 | |