OpenSessionInView模式总结

来源:互联网 发布:淘宝上买轮胎可靠吗 编辑:程序博客网 时间:2024/06/05 12:02

OpenSessionInView模式的起源:

OpenSessionInViewFilter是Spring提供的一个针对Hibernate的一个支持类,其主要意思是在发起一个页面请求时打开Hibernate的Session,一直保持这个Session,直到这个请求结束,具体是通过一个Filter来实现的。
由于Hibernate引入了Lazy Load特性,使得脱离Hibernate的Session周期的对象如果再想通过getter方法取到其关联对象的值,Hibernate会抛出一个 LazyLoad的Exception。所以为了解决这个问题,Spring引入了这个Filter,使得Hibernate的Session的生命周期变长。

 

一个简单的例子。

Java代码
  1. public void doFilter(ServletRequest request, ServletResponse response,   
  2.         FilterChain filterChain) throws IOException, ServletException {   
  3.         try{   
  4.                    
  5.                 Session session=HibernateSessionFactoryUtils.getSession();   
  6.                 request.setAttribute(HIBERNATE_SESSIN_KEY, session);   
  7.                 log.debug("客户端请求开始,Hibernate Session已打开.........");   
  8.                 filterChain.doFilter(request, response);   
  9.         }finally {   
  10.                 Object obj=request.getAttribute(HIBERNATE_SESSIN_KEY);   
  11.                 if(obj!=null&&obj instanceof Session){   
  12.                     Session session=(Session)obj;   
  13.                     session.close();   
  14.                     log.debug("客户端请求结束,Hibernate Session已关闭.........");   
  15.                 }else{   
  16.                     log.error("客户端请求结束,Hibernate Session未发现,请检查代码....");   
  17.                 }   
  18.             }   
  19. }  

 缺点:使用了OpenSessionInView 模式后造成了内存和数据库连接问题

由于使用了OpenSessionInView 模式,Session的生命周期变得非常长。虽然解决了Lazy Load的问题,但是带来的问题就是Hibernate的一级缓存,也就是Session级别的缓存的生命周期会变得非常长,那么如果你在你的 Service层做大批量的数据操作时,其实这些数据会在缓存中保留一份,这是非常耗费内存的。还有一个数据库连接的问题,存在的原因在于由于数据库的 Connection是和Session绑在一起的,所以,Connection也会得不到及时的释放。因而当系统出现业务非常繁忙,而计算量又非常大的时候,往往数据连接池的连接数会不够。这个问题我至今非常头痛,因为有很多客户对数据连接池的数量会有限制,不会给你无限制的增加下去。

在本地开发测试的时候没出现问题,但试想下如果流程中的某一步被阻塞的话,那在这期间connection就一直被占用而不释放。最有可能被阻塞的就是在写Jsp这步,一方面可能是页面内容大,response.write的时间长,另一方面可能是网速慢,服务器与用户间传输时间久。当大量这样的情况出现时,就有连接池连接不足,造成页面假死现象。

解决方案:

1,使用OpenSessionInView Interceptor来代替这个Filter

2,使用Hibernate.initialize()方法初始会延迟加载的对象

原创粉丝点击