解决OpenSessionInViewFilter无法增删改的问题

 

       我们在使用hibernate的时候,经常会碰到lazy属性,而在实际应用中,我们系统分为三层,对结果处理往往在service层,此时如果想对lazy加载的属性进行操作的时候,hibernate便会报错。

 

        解决办法:1、lazy=false,不推荐,每次加载的时候会多加载很多无用的SQL;

 

                            2、使用spring OpenSessionInViewFilter;

      OpenSessionInViewFilter所起的作用是,Spring拦截每次请求,并为每次绑定一个session,请求结束后,关闭session。

      我在使用OpenSessionInViewFilter,发现添加了这个类之后,之前的增删改操作失效了。

      经过长时间折腾,发现是由于事务的缘故。

       具体过程如下:spring有一个很强大的功能,便是事务管理, 这个功能使我们少编写了很多代码。一般情况下,我们是将事务管理配置在业务层,即service层。关于spring事务请参照其他资料。

      我的spring事务配置如下

      

<!-- SPRING会在程序抛出unchecked异常的时候回滚,对于try{}cache的异常则不处理 -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<!-- 需要由交给spring的aop来进行代理的方法的集合,如果应用有自己的方法需有由spring来进行事务控制必须添加方法-->
			<!-- 读取数据方法,一般采用只读事务-->
			<tx:method name="get*" isolation="DEFAULT" propagation="SUPPORTS"
				read-only="true" />
			<tx:method name="load*" isolation="DEFAULT" propagation="SUPPORTS"
				read-only="true" />
			<tx:method name="select*" isolation="DEFAULT" propagation="SUPPORTS"
				read-only="true" />
			<tx:method name="find*" isolation="DEFAULT" propagation="SUPPORTS"
				read-only="true" />
				<!-- 查询的日志隔离级别 为DEFAULT,默认也是DEFAULT,事务的传播行为,SUPPORTS,如果之前开启过事务,就加入那个事务,没有就非事务的方式运行 -->
			<tx:method name="query*" isolation="DEFAULT" propagation="SUPPORTS"
				read-only="true" />
				<!-- 除开以上定义的方法,其他方法的事务传播行为为REQUIRED,即有事务就加入事务,没有事务就新建一个事务 -->
			<tx:method name="*"  read-only="false"/>
		</tx:attributes>
	</tx:advice>




	<!--
		Spring采用AOP进行事务控制,这里指定了凡是实现了以com打头的包及其子包里以service.impl所有类的所有方法需要由事务进行控制
	-->
	<aop:config proxy-target-class="true">
		<aop:pointcut id="serviceOperation" expression="execution(* com..*.service.impl.*.*(..))" />
		<aop:advisor pointcut-ref="serviceOperation" advice-ref="txAdvice" />
	</aop:config>

	<bean id="transactionManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>

     说回主题,为什么不能增删改,

      那是因为你运行的方法没有开启事务,而hibernate的增删改操作是需要开启事务,所以不能增删改。

      运行的方法没有开启事务最直接的原因是配置出了问题,我的问题就是出在这里。

     

       最后说一下OpenSessionInViewFilter的弊;

       从它的作用范围我们知道,session会被用户持有整个请求过程,造成的问题便是session过多的被持有,造成连接数不够。

       其中的一种情况,业务处理耗费时间过长,访问用户过多都会造成这个问题。

       我采用的方法,lazy设为true,如果你有需求使用实例里面lazy属性,就请使用Hibernate.initialize方法强制实例化。

       补充:纠正一下上面说的OpenSessionInViewFilter,这个方法并不会造成连接数不够的情况发生,Hibernate获取连接数的行为发生在事务开始的时候,而OpenSessionInViewFilter只是把session绑定至当前请求,并不会开启事务,连接数不够的情况并不会发生。

       连接数不够的情况发生在一个事务的执行时间很长的情况,如上面我们说的将service层的所有方法让spring事务管理,如果其中一个业务过程处理时间较长,如上传文件,那么同时多个用户在上传超过连接池的连接数,此时便会出现连接数不够的情况。

      

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值