关于ThreadLocalSession和Transaction之间的关系
org.hibernate.context.ThreadLocalSessionContext is: A CurrentSessionContext
impl which scopes the notion of current session by the current thread of
execution. Unlike the JTA counterpart, threads do not give us a nice hook to
perform any type of cleanup making it questionable for this impl to actually
generate Session instances. In the interest of usability, it was decided to have
this default impl actually generate a session upon first request and then clean
it up after the org.hibernate.Transaction
associated with that session is committed/rolled-back. In order for ensuring
that happens, the sessions generated here are unusable until after Session.beginTransaction()
has been called.
If close() is called on a session managed by this
class, it will be automatically unbound.
Additionally, the static bind
and unbind
methods are provided to allow application code to explicitly control opening and
closing of these sessions. This, with some from of interception, is the
preferred approach. It also allows easy framework integration and one possible
approach for implementing long-sessions.
1.在没有显式地开始一个事务之前,不能使用session的任何数据访问方法。
2.一旦事务提交,session将自动close。
这种做法的意图非常明显,它将transaction的周期与session的同期也绑定在了一起, 实现了所谓的“session-per-request”编程模型。session-per-request就是session-per-transaction,这种编程模型把用户的一次请求做为一次独立的事物来处理,使用一个对应的session.这样,request(也就是thread),transaction,session三者的生命周期就变成一致的了。对绝大多数的应用, session-per-request几乎总是合理和正确的。在没有第三方管理事务或session(如jta和spring)的情况下,使用hibernate内置的threadlocal上下文来管理session是一个默认的选择。需要特别说明的是:如果在这种方式下,提交了一个事务之后,再使用getCurrentSession()来获取session时,将会得到一个新的session,旧的session已经从threadlocal中移除。但如果是我们是在实际应用中遇到这种情况,我们需要审视自己的设计是否真得需要这样做,还是我们的transaction提交的太早了?
关于Spring对Session的管理需要另作分析,
一方面,需要了解SpringSessionContext
另一方面,很多处理会和 HibernateTemplat有关系。从Spring的用户手册上看以知道:
HibernateTemplate 会确保当前Hibernate的 Session 实例的正确打开和关闭,并直接参与到事务管理中去。