论坛首页 Java企业应用论坛

spring+hibernate多数据源+动态切换 事务 lazyload一应俱全

浏览 14428 次
精华帖 (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次会出现错误的。

多数据源:管理系统数据源+游戏数据源

动态切换:游戏数据各服务器之间切换。

   发表时间:2011-04-15  
谢谢:http://guoweisong.iteye.com/blog/751482

虽然他也是转载的,虽然找不到原博主,虽然上面描述的事务问题没有遇到

但是描述的很详细,分析步骤很清晰!
0 请登录后投票
   发表时间:2011-04-15   最后修改:2011-04-15
我发现一个奇怪的问题,就是动态切换的时候ThreadLocal 居然没有保持set进去的值

private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();

-------------------------

这个地方不要用ThreadLocal 。。。 设置一个static变量来保存key值就行了。
0 请登录后投票
   发表时间:2011-04-16  
感觉这种设计方式不是很好吧,
0 请登录后投票
   发表时间:2011-04-16   最后修改:2011-04-16
大型的项目当中是不能切换数据源


不然会存在数据唯一性 的问题




0 请登录后投票
   发表时间:2011-04-16  
LZ有没想过用JTA做?
用JOTM配合JTA,配置多个数据源,多个seesionfactory
还能确保事务一致呢
0 请登录后投票
   发表时间:2011-04-17  
fairplay 写道
LZ有没想过用JTA做?
用JOTM配合JTA,配置多个数据源,多个seesionfactory
还能确保事务一致呢

jta没用过。 上面说的大概对于简单的系统没什么问题

数据唯一性 是什么问题?。不切换数据源怎么看多个数据库的数据?

还有我这个系统2个数据源的数据没有关联的。
0 请登录后投票
   发表时间:2011-04-20  
这种多数据源的还是用jta来得方便,JOTM就足够了,或者用一些容器的实现,比如websphere,不明白的是为啥要切换数据源,切换seesionfactory 不可以吗,可以仿照spring的多数据源实现一下就可以了,这个地方不太明白
0 请登录后投票
   发表时间:2011-04-20  
371937605 写道
这种多数据源的还是用jta来得方便,JOTM就足够了,或者用一些容器的实现,比如websphere,不明白的是为啥要切换数据源,切换seesionfactory 不可以吗,可以仿照spring的多数据源实现一下就可以了,这个地方不太明白

你没明白使用场景,多数据源归多数据源 动态切换归动态切换。
0 请登录后投票
   发表时间:2011-04-20  
ak121077313 写道
371937605 写道
这种多数据源的还是用jta来得方便,JOTM就足够了,或者用一些容器的实现,比如websphere,不明白的是为啥要切换数据源,切换seesionfactory 不可以吗,可以仿照spring的多数据源实现一下就可以了,这个地方不太明白

你没明白使用场景,多数据源归多数据源 动态切换归动态切换。

每个seesionfactory 榜定一个数据源,多个seesionfactory 不就是多数据源了吗?
动态的切换seesionfactory 不就是切换数据源了吗,可能我真没理解,哈哈
0 请登录后投票
论坛首页 Java企业应用版

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