Hibernate中对Session管理

转载:http://www.wangchao.net.cn/bbsdetail_51177.html

在各种Session 管理方案中, ThreadLocal 模式得到了大量使用。ThreadLocal 是Java中一种较为特殊的线程绑定机制。通过ThreadLocal存取的数据,总是与当前线程相关,也就是说,JVM 为每个运行的线程,绑定了私有的本地实例存取空间,从而为多线程环境常出现的并发访问问题提供了一种隔离机制。首先,我们需要知道,SessionFactory负责创建Session,SessionFactory是线程
安全的,多个并发线程可以同时访问一个SessionFactory 并从中获取Session 实例。而Session并非线程安全,也就是说,如果多个线程同时使用一个Session实例进行数据存取,则将会导致Session 数据存取逻辑混乱。下面是一个典型的Servlet,我们试图通过一个类
变量session实现Session的重用,以避免每次操作都要重新创建:

 

代码看上去正确无误,甚至在我们单机测试的时候可能也不会发生什么问题,但这样的代
  Hibernate Developer's Guide Version 1.0
  September 2, 2004 So many open source projects. Why not Open your Documents?码一旦编译部署到实际运行环境中,接踵而来的莫名其妙的错误很可能会使得我们摸不找头脑。
  问题出在哪里?
首先,Servlet 运行是多线程的,而应用服务器并不会为每个线程都创建一个Servlet实例,也就是说,TestServlet在应用服务器中只有一个实例(在Tomcat中是这样,其他的应用服务器可能有不同的实现),而这个实例会被许多个线程并发调用,doGet 方法也将被不同的线程反复调用,可想而知,每次调用doGet 方法,这个唯一的TestServlet 实例的session 变量都会被重置,线程A 的运行过程中,其他的线程如果也被执行,那么session的引用将发生改变,之后线程A 再调用session,可能此时的session 与其之前所用的session就不再一致,显然,错误也就不期而至。ThreadLocal的出现,使得这个问题迎刃而解。
  我们对上面的例子进行一些小小的修改:

 

可以看到,localSession 是一个ThreadLocal 类型的对象,在doGet 方法中,我们
  通过其set 方法将获取的session 实例保存,而在doSomething 方法中,通过get 方法取出session实例。这也就是ThreadLocal的独特之处,它会为每个线程维护一个私有的变量空间。实际上,其实现原理是在JVM 中维护一个Map,这个Map的key 就是当前的线程对象,而value则是线程通过ThreadLocal.set方法保存的对象实例。当线程调用ThreadLocal.get方法时,ThreadLocal会根据当前线程对象的引用,取出Map中对应的对象返回。这样,ThreadLocal通过以各个线程对象的引用作为区分,从而将不同线程的变量隔离开来。

 

Hibernate官方开发手册的示例中,提供了一个通过ThreadLocal维护Session的好
  榜样:

 

在代码中,只要借助上面这个工具类获取Session 实例,我们就可以实现线程范围内的Session 共享,从而避免了在线程中频繁的创建和销毁Session 实例。不过注意在线程结束时关闭Session。同时值得一提的是,新版本的Hibernate在处理Session的时候已经内置了延迟加载机制,只有在真正发生数据库操作的时候,才会从数据库连接池获取数据库连接,我们不必过于担心Session的共享会导致整个线程生命周期内数据库连接被持续占用。对于Web程序而言,我们可以借助Servlet2.3规范中新引入的Filter机制,轻松实现线程生命周期内的
Session管理(关于Filter的具体描述,请参考Servlet2.3规范)。Filter的生命周期贯穿了其所覆盖的Servlet(JSP也可以看作是一种特殊的Servlet)及其底层对象。Filter在Servlet被调用之前执行,在Servlet调用结束之后结束。因此,在Filter 中管理Session 对于Web 程序而言就显得水到渠成。下面是一个通过Filter 进行Session管理的典型案例:

 

 

通过在doFilter中获取和关闭Session,并在周期内运行的所有对象(Filter链中其余的Filter,及其覆盖的Servlet 和其他对象)对此Session 实例进行重用,保证了一个Http Request处理过程中只占用一个Session,提高了整体性能表现。在实际设计中,Session的重用做到线程级别一般已经足够,企图通过HttpSession实现用户级的Session重用反而可能导致其他的问题。凡事不能过火,Session重用也一样。
作者Blog:http://blog.csdn.net/jhxck/



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值