💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# 2.5\. 上下文相关的(Contextual)Session 使用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开发团队坚信,因为有好几个独立的`JTA TransactionManager`实现稳定可用,不论是否被部署到一个`J2EE`容器中,大多数(假若不是所有的)应用程序都应该采用`JTA`事务管理。基于这一点,采用`JTA`的上下文相关session可以满足你一切需要。 更好的是,从3.1开始,`SessionFactory.getCurrentSession()`的后台实现是可拔插的。因此,我们引入了新的扩展接口(`org.hibernate.context.CurrentSessionContext`)和新的配置参数(`hibernate.current_session_context_class`),以便对什么是“当前session”的范围和上下文(scope and context)的定义进行拔插。 请参阅`org.hibernate.context.CurrentSessionContext`接口的Javadoc,那里有关于它的契约的详细讨论。它定义了单一的方法,`currentSession()`,特定的实现用它来负责跟踪当前的上下文session。Hibernate内置了此接口的三种实现。 * `org.hibernate.context.JTASessionContext` - 当前session根据`JTA`来跟踪和界定。这和以前的仅支持JTA的方法是完全一样的。详情请参阅Javadoc。 * `org.hibernate.context.ThreadLocalSessionContext` - 当前session通过当前执行的线程来跟踪和界定。详情也请参阅Javadoc。 * `org.hibernate.context.ManagedSessionContext` - 当前session通过当前执行的线程来跟踪和界定。但是,你需要负责使用这个类的静态方法将`Session`实例绑定、或者取消绑定,它并不会打开(open)、flush或者关闭(close)任何`Session`。 前两种实现都提供了“每数据库事务对应一个session”的编程模型,也称作_每次请求一个session_。Hibernate session的起始和终结由数据库事务的生存来控制。假若你在纯粹的 Java SE之上采用自行编写代码来管理事务,而不使用JTA,建议你使用Hibernate `Transaction` API来把底层事务实现从你的代码中隐藏掉。如果你使用JTA,请使用JTA借口来管理Transaction。如果你在支持CMT的EJB容器中执行代码,事务边界是声明式定义的,你不需要在代码中进行任何事务或session管理操作。请参阅[第 11 章 _事务和并发_](../Text/pr01_split_000.html "第 11 章 事务和并发")一节来阅读更多的内容和示例代码。 `hibernate.current_session_context_class`配置参数定义了应该采用哪个`org.hibernate.context.CurrentSessionContext`实现。注意,为了向下兼容,如果未配置此参数,但是存在`org.hibernate.transaction.TransactionManagerLookup`的配置,Hibernate会采用`org.hibernate.context.JTASessionContext`。一般而言,此参数的值指明了要使用的实现类的全名,但那三种内置的实现可以使用简写,即"jta"、"thread"和"managed"。