2.5. 上下文相关的会话(Contextual Session)
使 用 Hibernate 的大多数应用程序需要某种形式的“上下文相关的”会话,特定的会话在整个特定的上下文范围内始终有效。然而,对不同类型的应用程序而言,要为什么是组成这 种“上下文”下一个定义通常是困难的;不同的上下文对“当前”这个概念定义了不同的范围。在 3.0 版本之前,使用 Hibernate 的程序要么采用自行编写的基于 ThreadLocal
的上下文会话,要么采用 HibernateUtil
这样的辅助类,要么采用第三方框架(比如 Spring 或 Pico),它们提供了基于代理(proxy)或者基于拦截器(interception)的上下文相关的会话。
从 3.0.1 版本开始,Hibernate 增加了 SessionFactory.getCurrentSession()
方法。一开始,它假定了采用 JTA
事务,JTA
事务定义了当前 session 的范围和上下文(scope 和 context)。因为有好几个独立的 JTA TransactionManager
实现稳定可用,不论是否被部署到一个 J2EE
容器中,大多数(假若不是所有的)应用程序都应该采用 JTA
事务管理。基于这一点,采用 JTA
的上下文相关的会话可以满足你一切需要。
更好的是,从 3.1 开始,SessionFactory.getCurrentSession()
的后台实现是可拔插的。因此,我们引入了新的扩展接口(org.hibernate.context.CurrentSessionContext
)和新的配置参数(hibernate.current_session_context_class
),以便对什么是当前会话的范围(scope)和上下文(context)的定义进行拔插。
请参阅 org.hibernate.context.CurrentSessionContext
接口的 Javadoc,那里有关于它的契约的详细讨论。它定义了单一的方法,currentSession()
,特定的实现用它来负责跟踪当前的上下文相关的会话。Hibernate 内置了此接口的三种实现:
org.hibernate.context.JTASessionContext
:当前会话根据JTA
来跟踪和界定。这和以前的仅支持 JTA 的方法是完全一样的。详情请参阅 Javadoc。org.hibernate.context.ThreadLocalSessionContext
:当前会话通过当前执行的线程来跟踪和界定。详情也请参阅 Javadoc。org.hibernate.context.ManagedSessionContext
:当前会话通过当前执行的线程来跟踪和界定。但是,你需要负责使用这个类的静态方法将Session
实例绑定、或者取消绑定,它并不会打开(open)、flush 或者关闭(close)任何Session
。
The first two implementations provide a "one session - one database transaction" programming model. This is also known and used as session-per-request. The beginning and end of a Hibernate session is defined by the duration of a database transaction. If you use programmatic transaction demarcation in plain JSE without JTA, you are advised to use the Hibernate Transaction
API to hide the underlying transaction system from your code. If you use JTA, you can utilize the JTA interfaces to demarcate transactions. If you execute in an EJB container that supports CMT, transaction boundaries are defined declaratively and you do not need any transaction or session demarcation operations in your code. Refer to 第 12 章 事务和并发 for more information and code examples.
hibernate.current_session_context_class
配置参数定义了应该采用哪个 org.hibernate.context.CurrentSessionContext
实现。注意,为了向下兼容,如果未配置此参数,但是存在 org.hibernate.transaction.TransactionManagerLookup
的配置,Hibernate 会采用org.hibernate.context.JTASessionContext
。一般而言,此参数的值指明了要使用的实现类的全名,但那三种内置的实现可以使用简写,即 "jta"、"thread" 和 "managed"。