hibernate.current_session_context_class属性配置

此设置的做用以下:

What does sessionFactory.getCurrentSession() do? First, you can call it
as many times and anywhere you
like, once you get hold of your SessionFactory (easy thanks to
HibernateUtil). The getCurrentSession()
method always returns the "current" unit of work. Remember that we
switched the configuration option for this
mechanism to "thread" in hibernate.cfg.xml? Hence, the scope of the
current unit of work is the current Java
thread that executes our application. However, this is not the full
truth. A Session begins when it is first
needed, when the first call to getCurrentSession() is made. It is then
bound by Hibernate to the current
thread. When the transaction ends, either committed or rolled back,
Hibernate also unbinds the Session from
the thread and closes it for you. If you call getCurrentSession() again,
you get a new Session and can start a
new unit of work. This thread-bound programming model is the most
popular way of using Hibernate. java

意思是说: 数据库

sessionFactory.getCurrentSession()能够完成一系列的工做,当调用时,
hibernate将session绑定到当前线程,事务结束后,hibernate
将session从当前线程中释放,而且关闭session。当再次调用getCurrentSession
()时,将获得一个新的session,并从新开始这一系列工做。
这样调用方法以下:

Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Event theEvent = new Event();
theEvent.setTitle(title);
theEvent.setDate(theDate);
session.save(theEvent);
session.getTransaction().commit();

不须要close session了。 编程


前提是改值设置为了thread. session


1 getCurrentSession建立的session会和绑定到当前线程,而openSession不会。 多线程

2 getCurrentSession建立的线程会在事务回滚或事物提交后自动关闭,而openSession必须手动关闭 并发

这里getCurrentSession本地事务(本地事务:jdbc)时 要在配置文件里进行以下设置 app

* 若是使用的是本地事务(jdbc事务)
<property name="hibernate.current_session_context_class">thread</property>
* 若是使用的是全局事务(jta事务)
<property name="hibernate.current_session_context_class">jta</property> 框架

getCurrentSession () 使用当前的session
openSession() 从新创建一个新的session

在一个应用程序中,若是DAO 层使用Spring 的hibernate 模板,经过Spring 来控制session 的生命周期,则首选getCurrentSession ()。 ui

使用Hibernate的大多数应用程序须要某种形式的“上下文相关的”session,特定的session在整个特定的上下文范围内始终有效。然而,对不一样类型的应用程序而言,要为何是组成这种“上下文”下一个定义一般是困难的;不一样的上下文对“当前”这个概念定义了不一样的范围。在3.0版本以前,使用Hibernate的程序要么采用自行编写的基于ThreadLocal的上下文session,要么采用HibernateUtil这样的辅助类,要么采用第三方框架(好比Spring或Pico),它们提供了基于代理(proxy)或者基于拦截器(interception)的上下文相关session。

从3.0.1版本开始,Hibernate增长了SessionFactory.getCurrentSession()方法。一开始,它假定了采用JTA事务,JTA事务定义了当前session的范围和上下文(scope and context)。Hibernate开发团队坚信,由于有好几个独立的JTATransactionManager实现稳定可用,不管是否被部署到一个J2EE容器中,大多数(倘若不是全部的)应用程序都应该采用JTA事务管理。基于这一点,采用JTA的上下文相关session能够知足你一切须要。

更好的是,从3.1开始,SessionFactory.getCurrentSession()的后台实现是可拔插的。所以,咱们引入了新的扩展接口(org.hibernate.context.CurrentSessionContext)和新的配置参数(hibernate.current_session_context_class),以便对什么是“当前session”的范围和上下文(scopeand context)的定义进行拔插。

请参阅org.hibernate.context.CurrentSessionContext接口的Javadoc,那里有关于它的契约的详细讨论。它定义了单一的方法,currentSession(),特定的实现用它来负责跟踪当前的上下文session。Hibernate内置了此接口的两种实现。

org.hibernate.context.JTASessionContext - 当前session根据JTA来跟踪和界定。这和之前的仅支持JTA的方法是彻底同样的。详情请参阅Javadoc。

org.hibernate.context.ThreadLocalSessionContext - 当前session经过当前执行的线程来跟踪和界定。详情也请参阅Javadoc。

这两种实现都提供了“每数据库事务对应一个session”的编程模型,也称做每次请求一个session。Hibernatesession的起始和终结由数据库事务的生存来控制。倘若你采用自行编写代码来管理事务(好比,在纯粹的J2SE,或者JTA/UserTransaction/BMT),建议你使用Hibernate TransactionAPI来把底层事务实现从你的代码中隐藏掉。若是你在支持CMT的EJB容器中执行,事务边界是声明式定义的,你不须要在代码中进行任何事务或session管理操做。请参阅第 11 章 事务和并发一节来阅读更多的内容和示例代码。

hibernate.current_session_context_class配置参数定义了应该采用哪一个org.hibernate.context.CurrentSessionContext实现。注意,为了向下兼容,若是未配置此参数,可是存在org.hibernate.transaction.TransactionManagerLookup的配置,Hibernate会采用org.hibernate.context.JTASessionContext。通常而言,此参数的值指明了要使用的实现类的全名,但那两个内置的实现可使用简写,即"jta"和"thread"。

一、getCurrentSession()与openSession()的区别? this

* 采用getCurrentSession()建立的session会绑定到当前线程中,而采用openSession()建立的session则不会* 采用getCurrentSession()建立的session在commit或rollback时会自动关闭,而采用openSession()建立的session必须手动关闭二、使用getCurrentSession()须要在hibernate.cfg.xml文件中加入以下配置:* 若是使用的是本地事务(jdbc事务)<property name="hibernate.current_session_context_class">thread</property>* 若是使用的是全局事务(jta事务)

<property name="hibernate.current_session_context_class">jta</property>

利于ThreadLocal模式管理Session
早在Java1.2推出之时,Java平台中就引入了一个新的支持:java.lang.ThreadLocal,给咱们在编写多线程程序
时提供了一种新的选择。ThreadLocal是什么呢?其实ThreadLocal并不是是一个线程的本地实现版本,它并非一个Thread,
而是thread local variable(线程局部变量)。也许把它命名为ThreadLocalVar更加合适。线程局部变量(ThreadLocal)
其实的功用很是简单,就是为每个使用某变量的线程都提供一个该变量值的副本,是每个线程均可以独立地改变本身的副本,
而不会和其它线程的副本冲突。从线程的角度看,就好像每个线程都彻底拥有一个该变量。
ThreadLocal是如何作到为每个线程维护变量的副本的呢?其实实现的思路很简单,在ThreadLocal类中有一个Map,
用于存储每个线程的变量的副本。好比下面的示例实现(为了简单,没有考虑集合的泛型):
public class HibernateUtil {

public static final ThreadLocal session =new ThreadLocal();

public static final SessionFactory sessionFactory;
static {
try {
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}

public static Session currentSession() throws HibernateException {
Session s = session.get();
if(s == null) {
s = sessionFactory.openSession();
session.set(s);
}
return s;
}

public static void closeSession() throws HibernateException {
Session s = session.get();
if(s != null) {
s.close();
}
session.set(null);
}
}

openSession() getCurrentSession() 有何不一样和关联呢?


在 SessionFactory 启动的时候, Hibernate 会根据配置建立相应的 CurrentSessionContext ,在 getCurrentSession() 被调用的时候,实际被执行的方法是 CurrentSessionContext.currentSession() 。在 currentSession() 执行时,若是当前 Session 为空, currentSession 会调用 SessionFactory 的 openSession 。因此 getCurrentSession() 对于 Java EE 来讲是更好的获取 Session 的方法。

相关文章
相关标签/搜索