细品hibernate的session

一、什么是session

    简单的来说,session类比于jdbc中的connection;

二、session的生命周期

     三大生命周期,参见:吾的hibernate总结;

三、细说session线程

session由sessionFactory创建

 

sessionFactory线程安全,

session线程不安全

 

解决session线程不安全问题

方案一

需要ThreadLocal;

ThreadLocal 是Java中一种较为特殊的线程绑定机制,通过ThreadLocal存取的数据,总是与当前线程相关,也就是说,JVM 为每个运行的线程,绑定了私有的本地实例存取空间,从而为多线程环境常出现的并发访问问题提供了一种隔离机制,ThreadLocal并不是线程本地化的实现,而是线程局部变量。

也就是说每个使用该变量的线程都必须为该变量提供一个副本,每个线程改变该变量的值仅仅是改变该副本的值,而不会影响其他线程的该变量的值,ThreadLocal是隔离多个线程的数据共享,不存在多个线程之间共享资源,因此不再需要对线程同步。

 

例子

public class HibernateUtil {  
 
public static final SessionFactory sessionFactory;  
public static final ThreadLocal session = new ThreadLocal();  
//创建 Configuration容器,可以把其理解为一容器,容器的生命周期就是在一个线程中 
static{  
 
try{  
 
Configuration configuration=new Configuration().configure(); 
sessionFactory = configuration.buildSessionFactory();  
 
}catch (Throwable ex){  
 
System.err.println("Initial SessionFactory creation failed." + ex);  
throw new ExceptionInInitializerError(ex);  
}  
}  
 
public static Session currentSession() throws HibernateException{  
Session s = (Session) session.get();  
if (s == null)  
{  
s = sessionFactory.openSession();  
session.set(s); //将session装入 Configuration容器
}  
return s;  
}  
 
public static void closeSession() throws HibernateException {  
Session s = (Session) session.get();  
if (s != null)  
s.close();//清空容器
session.set(null);  
}  
} 


解决方案二

对象的生命周期与本地线程绑定(通过Thread-local传播Session,线程本地化)

¨       如果把 Hibernate 配置文件的 hibernate.current_session_context_class 属性值设为 thread, Hibernate 就会按照与本地线程绑定的方式来管理 Session

¨       Hibernate 按以下规则把 Session 与本地线程绑定

          当一个线程(threadA)第一次调用 SessionFactory 对象的 getCurrentSession() 方法时, 该方法会创建一个新的 Session(sessionA) 对象, 把该对象与 threadA 绑定, 并将 sessionA 返回

          threadA 再次调用 SessionFactory 对象的 getCurrentSession() 方法时, 该方法将返回 sessionA 对象

          threadA 提交 sessionA 对象关联的事务时, Hibernate 会自动清理 sessionA 对象的缓存, 然后提交事务, 关闭 sessionA 对象. threadA 撤销 sessionA 对象关联的事务时, 也会自动关闭 sessionA 对象

          threadA 再次调用 SessionFactory 对象的 getCurrentSession() 方法时, 该方法会又创建一个新的 Session(sessionB) 对象, 把该对象与 threadA 绑定, 并将 sessionB 返回

 

配置:

¨       hibernate.cfg.xml文件中增加

          <!-- 配置session的线程本地化 threadLocal -->

           <property name="current_session_context_class">thread</property>

¨       不是调用sessionFactory.openSession().而是调用sessionFactory. getCurrentSession().获取session对象.从当前的线程提取session

          当前线程如果存在session对象,取出直接使用

          当前线程如果不存在session对象,获取一个新的session对象和当前的线程绑定

 

 

 

 


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章