`
horizonhyg
  • 浏览: 58712 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

Hibernate中对Session管理

阅读更多

在各种Session 管理方案中, ThreadLocal 模式得到了大量使用。ThreadLocal 是Java中一种较为特殊的线程绑定机制。通过ThreadLocal存取的数据,总是与当前线程相关,也就是说,JVM 为每个运行的线程,绑定了私有的本地实例存取空间,从而为多线程环境常出现的并发访问问题提供了一种隔离机制。首先,我们需要知 道,SessionFactory负责创建Session,SessionFactory是线程
  安全的,多个并发线程可以同时访问一个SessionFactory 并从中获取Session 实例。而
  Session并非线程安全,也就是说,如果多个线程同时使用一个Session实例进行数据存取,
  则将会导致Session 数据存取逻辑混乱。下面是一个典型的Servlet,我们试图通过一个类
  变量session实现Session的重用,以避免每次操作都要重新创建:
  public class TestServlet extends HttpServlet {
  private Session session;
  public void doGet( HttpServletRequest request,
  HttpServletResponse response)
  throws ServletException, IOException {
  session = getSession();
  doSomething();
  session.flush();
  }
  public void doSomething(){
  ......//基于session的存取操作
  }
  }
  代码看上去正确无误,甚至在我们单机测试的时候可能也不会发生什么问题,但这样的代
  码一旦编译部署到实际运行环境中,接踵而来的莫名其妙的错误很可能会使得我们摸不找头脑。
  问题出在哪里?
  首先,Servlet 运行是多线程的,而应用服务器并不会为每个线程都创建一个Servlet
  实例,也就是说,TestServlet在应用服务器中只有一个实例(在Tomcat中是这样,其他的
  应用服务器可能有不同的实现),而这个实例会被许多个线程并发调用,doGet 方法也将被不
  同的线程反复调用,可想而知,每次调用doGet 方法,这个唯一的TestServlet 实例的
  session 变量都会被重置,线程A 的运行过程中,其他的线程如果也被执行,那么session
  的引用将发生改变,之后线程A 再调用session,可能此时的session 与其之前所用的
  session就不再一致,显然,错误也就不期而至。
  ThreadLocal的出现,使得这个问题迎刃而解。
  我们对上面的例子进行一些小小的修改:
  public class TestServlet extends HttpServlet {
  private ThreadLocal localSession = new ThreadLocal();
  public void doGet( HttpServletRequest request,
  HttpServletResponse response)
  throws ServletException, IOException {
  localSession.set(getSession());
  doSomething();
  session.flush();
  }
  public void doSomething(){
  Session session = (Session)localSession.get();
  ......//基于session的存取操作
  }
  }
  可以看到,localSession 是一个ThreadLocal 类型的对象,在doGet 方法中,我们
  通过其set 方法将获取的session 实例保存,而在doSomething 方法中,通过get 方法取
  出session实例。
  这也就是ThreadLocal的独特之处,它会为每个线程维护一个私有的变量空间。实际上,
  其实现原理是在JVM 中维护一个Map,这个Map的key 就是当前的线程对象,而value则是
  线程通过ThreadLocal.set方法保存的对象实例。当线程调用ThreadLocal.get方法时,
  ThreadLocal会根据当前线程对象的引用,取出Map中对应的对象返回。
  这样,ThreadLocal通过以各个线程对象的引用作为区分,从而将不同线程的变量隔离开
  来。
  Hibernate官方开发手册的示例中,提供了一个通过ThreadLocal维护Session的好
  榜样:
  public class HibernateUtil {
  private static SessionFactory sessionFactory;
  static {
  try {
  // Create the SessionFactory
  sessionFactory = new
  Configuration().configure().buildSessionFactory();
  } catch (HibernateException ex) {
  throw new RuntimeException(
  "Configuration problem: " + ex.getMessage(),
  ex
  );
  }
  }
  public static final ThreadLocal session = new ThreadLocal();
  public static Session currentSession() throws HibernateException
  {
  Session s = (Session) session.get();
  // Open a new Session, if this Thread has none yet
  if (s == null) {
  s = sessionFactory.openSession();
  session.set(s);
  }
  return s;
  }
  public static void closeSession() throws HibernateException {
  Session s = (Session) session.get();
  session.set(null);
  if (s != null)
  s.close();
  }
  }
  在代码中,只要借助上面这个工具类获取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管理的典型案例:
  public class PersistenceFilter implements Filter
  {
  protected static ThreadLocal hibernateHolder = new ThreadLocal();
  public void doFilter(ServletRequest request, ServletResponse
  response, FilterChain chain)
  throws IOException, ServletException
  {
  hibernateHolder.set(getSession());
  try
  {
  ......
  chain.doFilter(request, response);
  ......
  }
  finally
  {
  Session sess = (Session)hibernateHolder.get();
  if (sess != null)
  {
  hibernateHolder.set(null);
  try
  {
  sess.close();
  }
  catch (HibernateException ex) {
  throw new ServletException(ex);
  }
  }
  }
  }
  ......
  }
  通过在doFilter中获取和关闭Session,并在周期内运行的所有对象(Filter链中其
  余的Filter,及其覆盖的Servlet 和其他对象)对此Session 实例进行重用,保证了一个
  Http Request处理过程中只占用一个Session,提高了整体性能表现。
  在实际设计中,Session的重用做到线程级别一般已经足够,企图通过HttpSession实
  现用户级的Session重用反而可能导致其他的问题。凡事不能过火,Session重用也一样。
  作者Blog:http://blog.csdn.net/jhxck/

分享到:
评论

相关推荐

    Hibernate-nosession

    本文将深入探讨Hibernate-nosession的概念、应用场景以及如何在实际代码中实现。 首先,理解什么是Hibernate Session。Session是Hibernate中的核心接口,它充当了应用程序和数据库之间的桥梁,负责对象的持久化操作...

    hibernate中session的管理

    在实际开发中,除了使用ThreadLocal,还有其他几种Session管理策略,例如: 1. **Session per Request/Transaction**:每个HTTP请求或数据库事务分配一个Session。这通常是Web应用程序的最佳实践,因为HTTP请求是...

    Hibernate(session管理)

    本文将深入探讨Hibernate中的核心概念——Session管理。 首先,理解Session在Hibernate中的角色至关重要。Session是Hibernate的主要工作单元,它是应用程序与数据库之间的桥梁。它负责保存、检索和更新Java对象,...

    Hibernate Session释放模式

    这是最常见的Session管理方式,通常与Spring的@Transactional注解结合使用。每个数据库事务开始时创建Session,事务结束时关闭Session。这种方式简单且易于理解,能保证事务的ACID特性,但可能会导致大量的短连接,...

    Hibernate_Session_Transaction

    在Java的持久化框架Hibernate中,`Session`和`Transaction`是两个至关重要的概念,它们在数据管理和事务处理中起到核心作用。这篇文章将深入解析这两个概念及其相关知识点。 `Session`是Hibernate提供的一种与...

    重写hibernate的session简单增删改查

    在实际开发中,为了满足特定需求,有时我们需要对Hibernate的默认Session行为进行扩展或覆盖。例如,可能需要添加日志记录、事务控制、性能优化等功能。这就需要我们创建一个自定义的Session工厂(SessionFactory)...

    hibernate和session学习

    通过Hibernate,我们可以将数据库中的表与Java类进行映射,从而实现对数据库的操作,而无需编写大量的SQL语句。这极大地提高了开发效率,降低了代码的复杂性。 在Hibernate中,`SessionFactory`是核心组件之一,它...

    实现自己的Hibernate框架之Session 方法实现

    在IT行业中,数据库操作是应用程序开发中的重要环节,而Hibernate作为一个强大的对象关系映射(ORM)框架,极大地简化了Java应用程序对数据库的操作。本篇文章将深入探讨如何实现自己的Hibernate框架,特别是Session...

    Hibernate_11session

    通过以上介绍,我们可以看到Hibernate Session在数据库操作中的核心地位,正确理解和使用Session是掌握Hibernate的关键。实践中的具体应用需要结合项目需求,灵活运用这些知识,以实现高效、稳定的数据库访问。

    hibernate session生命周期示例

    通过合理的Session管理,我们可以减少数据库交互的复杂性,提高程序性能,并避免数据一致性问题。实践中,还要注意避免频繁打开和关闭Session,以及合理控制事务的粒度,以达到最佳的性能效果。

    Hibernate的Session的javadoc

    Hibernate的Session接口是Java应用程序与Hibernate之间主要的运行时交互接口,它提供了对持久化对象的创建、读取和删除操作。Session的概念是基于对象的状态管理和数据库事务的,它的生命周期通常与一个物理事务绑定...

    hibernate02:session对象、hql查询、在线查询也叫对象查询、离线查询

    在Hibernate中,`Session`是应用程序与数据库之间的桥梁,它是ORM(Object-Relational Mapping)的主要工作接口。`Session`提供了在数据库中保存、更新和删除对象的方法,同时也负责加载或检索对象。它具有事务管理...

    hibernate的session.flush

    总结来说,`Session.flush()`是Hibernate中不可或缺的一部分,它确保了数据库与应用程序的同步,同时也涉及到了缓存管理、事务控制等多个重要概念。开发者在使用Hibernate时,应当合理运用`flush()`,以提高应用的...

    Hibernate中获取Session的两种方式代码示例

    Hibernate中获取Session的两种方式代码示例 Hibernate 是一个流行的基于Java的持久层框架,提供了对数据库的访问和操作。Session 是 Hibernate 中一个核心概念,负责管理应用程序与数据库之间的交互。获取 Session ...

    hibernate--3.Hibernate数据持久化(通过 Session 操纵对象)

    首先,我们需要理解Session在Hibernate中的角色。Session是Hibernate的核心接口之一,它负责对象的持久化操作,比如保存、更新、删除和检索对象。Session对象就像一个临时的工作区域,用于在应用程序和数据库之间...

    对Hibernate Session做一个简单的包装

    然而,在实际开发中,我们往往需要根据项目需求对其进行定制,例如添加事务管理、异常处理、日志记录等功能,这就涉及到了对`Session`的封装。 在提供的`HibernateSessionWrapper.java`文件中,我们可以预期它实现...

    Spring与Hibernate集成中的session

    本文将详细探讨Spring与Hibernate的集成,特别是如何在集成环境中使用和管理`Session`。 首先,Spring作为一个轻量级的框架,提供了强大的依赖注入(DI)和面向切面编程(AOP)功能,它可以帮助我们解耦应用程序...

    JAVA的hibernate手动获取session的方法

    本篇将详细讲解如何在Hibernate中手动获取Session,以及涉及到的相关配置和连接管理。 首先,理解Hibernate的核心组件——Session。Session是Hibernate中的工作单元,它是与数据库交互的主要接口,负责保存、更新和...

    day36 11-Hibernate中的事务:当前线程中的session

    本文将深入探讨Hibernate中的事务处理,特别是“当前线程中的Session”这一概念,以及如何在实际开发中有效地利用它。 在Hibernate中,Session是与持久化层交互的主要接口,它负责对象的持久化、检索、更新和删除等...

    hibernate的核心接口--Session

    - **定义**: Session 是 Hibernate 框架中最常用的接口之一,它又被称为持久化管理器。Session 负责所有与数据库交互的工作,包括管理持久化对象的生命周期,并通过提供第一级别的高级缓存来确保持久化对象的数据与...

Global site tag (gtag.js) - Google Analytics