"proxied" 状态对于 Hibernate Session 意味着什么

What does "proxied" state means for a Hibernate Session

我在 Jboss 网站上看到了关于 Hibernate 文档的这一行。

Because Hibernate can't bind the "current session" to a transaction, 
as it does in a JTA environment, it binds it to the current Java thread
when i do transction demarcation with plain JDBC. 
It is opened when getCurrentSession() is called for the first time, 
but in a "proxied" state that doesn't allow you to do anything except 
start a transaction.

那么,作者这里的"proxied state"到底是什么意思呢。他们有什么 link 到 代理对象?

如果没有 JTA,事务管理是通过 JDBC Connection 的 commit/rollback 方法完成的。

这意味着您必须将一个 JDBC 连接绑定到当前的 运行 Hibernate 会话和当前的逻辑事务。

因为将 JDBC 连接传递给所有 Hibernate Session 方法将是一个糟糕的设计解决方案,您必须改用线程本地存储。

Hibernate 具有灵活的 CurrentSessionContext,提供以下替代方案:

  • JTASessionContext
  • ManagedSessionContext
  • ThreadLocalSessionContext

因此,如果您选择 ThreadLocaSessionContext,则底层 JDBC 连接将绑定到 Thread 本地存储,并使其可供当前 Thread 运行 Session 使用。

如果您使用 Spring,则不应依赖 Hibernate TreadLocal 上下文,而应使用 Spring 特定的事务管理支持,该支持由以下人员实现:

  • SpringJtaSessionContext
  • Spring会话上下文

至于代理状态,Hibernate TreadLocalContext 使用Hibernate Session 的代理:

protected Session wrap(Session session) {
    final TransactionProtectionWrapper wrapper = new TransactionProtectionWrapper( session );
    final Session wrapped = (Session) Proxy.newProxyInstance(
            Session.class.getClassLoader(),
            SESSION_PROXY_INTERFACES,
            wrapper
    );
    wrapper.setWrapped( wrapped );
    return wrapped;
}

允许当前 Session 在 Session.close() 方法被调用时 解除绑定 自身形成 TreadLocal 存储。

// If close() is called, guarantee unbind()
if ( "close".equals( methodName ) ) {
    unbind( realSession.getSessionFactory() );
}