`

利于ThreadLocal管理Hibernate Session

阅读更多

在利用Hibernate开发DAO模块时,我们和Session打的交道最多,所以如何合理的管理Session,避免Session的频繁创建和销毁,对于提高系统的性能来说是非常重要的,以往是通过eclipse的插件来自动完成这些代码的,当然效果是不错的,但是总是觉得不爽(没有读懂那些冗长的代码),所以现在打算自己实现Session管理的代码。我们知道Session是由SessionFactory负责创建的,而SessionFactory的实现是线程安全的,多个并发的线程可以同时访问一个SessionFactory并从中获取Session实例,那么Session是否是线程安全的呢?很遗憾,答案是否定的。Session中包含了数据库操作相关的状态信息,那么说如果多个线程同时使用一个Session实例进行CRUD,就很有可能导致数据存取的混乱,你能够想像那些你根本不能预测执行顺序的线程对你的一条记录进行操作的情形吗?
      在Session的众多管理方案中,我们今天来认识一种名为ThreadLocal模式的解决方案。
      早在Java1.2推出之时,Java平台中就引入了一个新的支持:java.lang.ThreadLocal,给我们在编写多线程程序时提供了一种新的选择。ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是thread local variable(线程局部变量)。也许把它命名为ThreadLocalVar更加合适。线程局部变量(ThreadLocal)其实的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有一个该变量。
      ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单,在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本。比如下面的示例实现(为了简单,没有考虑集合的泛型):

  1. public class ThreadLocal {   
  2.      private Map values = Collections.synchronizedMap(new HashMap());   
  3.      public Object get() {   
  4.         Thread currentThread = Thread.currentThread();    
  5.         Object result = values.get(currentThread);    
  6.         if(result == null&&!values.containsKey(currentThread)) {   
  7.            result = initialValue();   
  8.            values.put(currentThread, result);    
  9.         }   
  10.         return result;    
  11.      }   
  12.      public void set(Object newValue) {   
  13.         values.put(Thread.currentThread(), newValue);   
  14.      }   
  15.      public Object initialValue() {   
  16.         return null;    
  17.      }   
  18. }   

      那麽具体如何利用ThreadLocal来管理Session呢?Hibernate官方文档手册的示例之中,提供了一个通过ThreadLocal维护Session的好榜样:

  1. public class HibernateUtil {   
  2.        public static final SessionFactory sessionFactory;   
  3.        static {   
  4.            try {   
  5.                  sessionFactory = new Configuration().configure()   
  6.                                    .buildSessionFactory();   
  7.            } catch (Throwable ex) {   
  8.                 throw new ExceptionInInitializerError(ex);   
  9.            }   
  10.        }   
  11.        public static final ThreadLocal session =    
  12.                                             new ThreadLocal();   
  13.        public static Session currentSession() throws HibernateException {   
  14.                Session s = session.get();   
  15.                if(s == null) {   
  16.                      s = sessionFactory.openSession();   
  17.                      session.set(s);   
  18.                }   
  19.                return s;   
  20.        }   
  21.        public static void closeSession() throws HibernateException {   
  22.                 Session s = session.get();   
  23.                 if(s != null) {   
  24.                       s.close();   
  25.                 }   
  26.                 session.set(null);   
  27.        }   
  28. }  

     只要借助上面的工具类获取Session实例,我们就可以实现线程范围内的Session共享,从而避免了线程中频繁的创建和销毁Session实例。当然,不要忘记在用完后关闭Session。
     写到这里,想再多说一些,也许大多数时候我们的DAO并不会涉及到多线程的情形,比如我们不会将DAO的代码写在Servlet之中,那样不是良好的设计,我自己通常会在service层的代码里访问DAO的方法。但是我还是建议采用以上的工具类来管理Session,毕竟我们不能仅仅考虑今天为自己做什么,还应该考虑明天为自己做什么!

分享到:
评论
1 楼 jerry8086 2008-12-15  
曾经因为使用AOP管理事务,而不得不在service和dao之间传session而苦恼。但是在博主的这篇文章中,我找到了答案。真心的感谢博主!

相关推荐

    使用ThreadLocal管理“session”数据

    在Web应用中,特别是对于"session"数据的管理,ThreadLocal可以作为一种有效的解决方案。 1. **什么是Session?** Session是HTTP协议中的一个概念,用于存储用户在服务器端的状态信息。当用户登录网站后,服务器会...

    hibernate中session的管理

    本篇文章将详细探讨Hibernate中Session的管理,特别是如何利用ThreadLocal解决并发问题。 首先,SessionFactory是Hibernate的核心组件,它是一个线程安全的工厂类,用于创建Session实例。SessionFactory通常在应用...

    Hibernager_Session_Manager_ThreadLocal

    标题“Hibernage_Session_Manager_ThreadLocal”涉及到的是Hibernate框架中的一种优化策略——使用ThreadLocal管理Session。在Java Web开发中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它帮助开发者将...

    Hibernate用ThreadLocal模式(线程局部变量模式)管理Session

    总的来说,ThreadLocal模式在Hibernate中用于管理Session,解决了多线程环境下Session的共享问题,实现了线程间的隔离,提高了系统的稳定性和效率。通过合理地使用ThreadLocal,开发者可以构建出更高效、更安全的多...

    JAVA ThreadLocal类深入

    Hibernate框架在处理数据库操作时,使用ThreadLocal来管理Session,确保每个线程都有自己独立的Session对象。这样,即使多个线程并发执行,每个线程也不会干扰其他线程的Session,避免了数据错乱的问题。例如,...

    ThreadLocal的几种误区

    3. 存储数据库会话:在Spring Hibernate ORM中,ThreadLocal常用来保存数据库连接的Session,确保每个线程有自己的Session,避免线程间的资源冲突。 总之,ThreadLocal是一个强大的工具,但理解其工作原理和潜在...

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

    使用ThreadLocal Session的一个关键好处是事务的自动管理。当开启一个新的Session时,Hibernate会隐式地开始一个事务;当Session关闭时,如果之前没有遇到异常,那么事务就会被提交;如果有异常,事务会被回滚,从而...

    hibernate常用方法集合

    综上所述,`HibernateSessionFactory`是Hibernate应用程序的核心组件,它通过ThreadLocal实现线程安全的Session管理,简化了数据库操作,同时提供了事务处理、实体管理和查询等功能,使得Java开发人员能够更加专注于...

    J2EE利用Hibernate采用B/S架构网页设计

    private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>(); private static Configuration configuration = new Configuration(); private static org.hibernate.SessionFactory ...

    struts2+hibernate3 open session in view

    这通常通过`ThreadLocal`实现,使得每个线程都有自己的Session副本。 3. 懒加载处理:由于OSIV模式下Session保持开放,因此在视图层处理懒加载对象时,不再会出现“Session已关闭”的错误。但要注意,如果在视图层...

    正确理解ThreadLocal.pdf

    1. **数据库连接管理**:如上文的Hibernate示例,通过`ThreadLocal`管理每个线程的数据库连接,确保每个线程拥有独立的连接资源,避免了资源竞争。 2. **事务处理**:在事务管理中,`ThreadLocal`可以用于维护每个...

    ThreadLocal应用示例及理解

    以上就是关于ThreadLocal的基本概念、使用方法、生命周期管理和实际应用示例的详细解释。了解并熟练掌握ThreadLocal可以帮助我们编写出更高效、更安全的多线程代码。在Java并发编程中,ThreadLocal是一个不可或缺的...

    ThreadLocal

    ThreadLocal是Java编程语言中的一个类,用于在多线程环境中提供线程局部变量。...合理的使用能够帮助我们编写出更高效、更易于维护的多线程程序,但也要避免滥用,因为它可能会引入难以察觉的并发问题和内存管理问题。

    课程hibernate的事务和并发.pdf

    这种方式被称为ThreadLocal Session和Open Session in View模式,能够简化事务和Session的生命周期管理。 在实际应用中,需要确保正确地开启和结束Session及事务,并将其与数据访问操作结合。HibernateUtil类可以...

    从ThreadLocal的使用到Spring的事务管理

    本文将深入探讨ThreadLocal的使用以及Spring框架中的事务管理,这两个主题都是Java开发人员必须掌握的关键技能。 首先,让我们了解ThreadLocal。ThreadLocal是Java提供的一种线程绑定变量的工具类,它允许我们在一...

    通向架构师的道路(第七天)之漫谈使用ThreadLocal改进你的层次的划分

    ThreadLocal自JDK 1.2起就存在,它不是一个线程,而是一种管理线程局部变量的机制。每个线程都有其独立的ThreadLocal变量副本,这样每个线程都可以独立地修改自己的副本而不影响其他线程。这有助于避免并发问题,...

    hibernate

    - **作用**:`Session` 是 Hibernate 运作的核心,负责对象的生命周期管理、事务管理和数据库访问。 - **注意事项**:`Session` 不是线程安全的,多个线程共享一个 `Session` 可能会导致数据混乱。可以使用 `...

    基于Hibernate的数据持久层关键技术的研究

    2. **ThreadLocal模式**:在多线程环境下,使用ThreadLocal来管理Hibernate的Session可以避免线程安全问题。每个线程都有自己的Session实例,这样可以确保数据访问的线程安全性。 3. **静态工厂方法**:为了提高...

    入研究java.lang.ThreadLocal类.docx

    **目的**:管理 Hibernate 的 Session,确保每个线程都有独立的 Session 实例。 **关键代码段**: ```java public class HibernateUtil { private static Log log = LogFactory.getLog(HibernateUtil.class); ...

Global site tag (gtag.js) - Google Analytics