关于openSessionInView的问题
来源:互联网 发布:美国eia数据在那里看 编辑:程序博客网 时间:2024/06/09 18:56
openSessionInView实现Hibernate的延迟加载功能。其主要意思是在发起一个页面请求时打开Hibernate的Session,一直保持这个Session,直到这个请求结束,具体是通过一个Filter来实现的。
由于Hibernate引入了Lazy Load特性,使得脱离Hibernate的Session周期的对象如果再想通过getter方法取到其关联对象的值,Hibernate会抛出一个LazyLoad的Exception。所以为了解决这个问题,Spring引入了这个Filter,使得Hibernate的Session的生命周期变长。
spring中对OpenSessionInViewFilter的描述如下:
它是一个Servlet2.3过滤器,用来把一个Hibernate Session和一次完整的请求过程对应的线程相绑定。目的是为了实现"Open Session in View"的模式。
例如: 它允许在事务提交之后延迟加载显示所需要的对象。
openSessionInView需要在web.xml中加入如下配置(此监听器应该在struts2的filter前面):
<filter> <filter-name>openSessionInView</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> </filter> <filter-mapping> <filter-name>openSessionInView</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>如果在spring中没有配置事务,在进行增删改时,会抛出
org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.
产生原因:
在网上查了查,这个问题的原因原来是这样的
OpenSessionInViewFilter在getSession的时候,会把获取回来的session的flush mode 设为FlushMode.NEVER。然后把该sessionFactory绑定到TransactionSynchronizationManager,使request的整个过程都使用同一个session,在请求过后再接除该sessionFactory的绑定,最后closeSessionIfNecessary根据该session是否已和transaction绑定来决定是否关闭session。在这个过程中,若HibernateTemplate 发现自当前session有不是readOnly的transaction,就会获取到FlushMode.AUTO Session,使方法拥有写权限。
也即是,如果有不是readOnly的transaction就可以由Flush.NEVER转为Flush.AUTO,拥有insert,update,delete操作权限,如果没有transaction,并且没有另外人为地设flush model的话,则doFilter的整个过程都是Flush.NEVER。所以受transaction保护的方法有写权限,没受保护的则没有。
解决方法:
在beans.xml中配置事务,并且配置事务的传播特性,表明对于以create、delete、update开头的所有方法设置默认事务支持
<bean id="transactionManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory" /></bean><!-- 配置事务的传播特性 ,指定事务管理器--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!-- 配置详细的事务语义 --> <tx:attributes> <tx:method name="create*" propagation="REQUIRED" /> <tx:method name="delete*" propagation="REQUIRED" /><tx:method name="update*" propagation="REQUIRED" /><tx:method name="*" read-only="true" /> </tx:attributes> </tx:advice>对于Spring的OpenSessionInViewFilter来说,虽然数据库连接被保持了过长的时间,但是并没有锁定数据库资源,特别是事务资源。因为Spring的事务是通过TransactionInterceptor来实现的,在MVC结构中,当最后一个业务bean被调用结束以后,Transaction就已经被提交了。此后,虽然数据库连接还保持中,但是数据库资源没有锁定问题。数据库连接应该尽早被释放,以缓解数据库资源的压力,延迟很久才释放,会导致需要更多的数据库连接,并发量大的时候经常出现连接池耗尽。Session被延迟很久释放,那么Session占用的一级缓存也会占用比较长时间,这意味着会无谓消耗更多的JVM内存。OpenSessionInView虽然确实方便,但是还是慎用.
对于性能方面看看这个老帖子吧:http://www.iteye.com/topic/17501
- 关于openSessionInView的问题
- openSessionInView的问题?
- OpensessionInView的FlushMode问题
- 关于OpenSessionInView
- 关于OpenSessionInView的学习和使用
- SSH框架中的使用OpenSessionInView的问题
- SSH框架中的使用OpenSessionInView的问题
- 由OpenSessionInView引出的List复制问题
- OpenSessionInView 与 transaction 问题
- Hibernate/Spring/Struts架构使用OpenSessionInView的问题
- 解决了Hibernate+Spring+Struts架构使用OpenSessionInView的问题
- Hibernate/Spring/Struts架构使用OpenSessionInView的问题
- Hibernate/Spring/Struts架构使用OpenSessionInView的问题
- Hibernate/Spring/Struts架构使用OpenSessionInView的问题
- 使用OpenSessionInView解决懒加载需要注意的问题
- spring的OpenSessionInView用法
- LazyInitializationException的OpenSessionInView解决方案
- OpenSessionInView的原理图总结.
- ALM 解决方案之TechExcel DevSuite 评估报告 - 2
- Go语言_eclipse环境搭建(继上篇)
- poj 3767 I Wanna Go Home
- 黑马程序员_Java学习日记第二天--面向对象
- SSL协议及其应用
- 关于openSessionInView的问题
- 转载一篇文章试试 C#判断点在线段的左右侧
- Spring3表达式语言(SpEL)学习笔记
- C# 通讯时字节流和结构体互转
- vim tab设置为4个空格
- ZOJ 1241 Geometry Made Simple
- 黑马程序员_Java学习日记第三天-多态、内部类、异常处理
- Spring 3.0参考之SpEL
- 黑马程序员_Java学习日记第四天-线程、Java1.5的新特性