在EJB 中 配备Hibernate支持JTA
在EJB 中 配置Hibernate支持JTAFinally, ?搞清楚了些Hibernate 的对JTA 的支持。??有几个非常重要的propert
在EJB 中 配置Hibernate支持JTA
Finally, ?搞清楚了些Hibernate 的对JTA 的支持。?
?
有几个非常重要的property 需要配置
<prop key="hibernate.current_session_context_class">
jta
</prop>
?
<prop ? key="hibernate.transaction.manager_lookup_class">
org.hibernate.transaction.WebSphereTransactionManagerLookup
</prop>
<prop key="hibernate.transaction.factory_class">
org.hibernate.transaction.CMTTransactionFactory
</prop>
1, hibernate.transaction.manager_lookup_class 是用来在SessionFactory 起来的时候调用在 获取 TransactionManager 的, 在 WebSphere 下比较特殊用 这个 ?WebSphereTransactionManagerLookup。 其它的很多应用服务器比如GlassFish 是通过JNDI 来得到 TransactionManager 的。 GlassFish 下用 ???org.hibernate.transaction.SunONETransactionManagerLookup? ? ?这样Hibernate就可以拿到正确的TransactionManager 了。
2,?hibernate.current_session_context_class ?是用来配置 SessionContext 的, 它跟SessionFactory 一样可以理解成是个单例。 一个Hibernate configuration 对应一个SessionFactory, 一个SessionFactory 对应一个CurrentSessionContext. ?在应用程序中 我们最好是都通过 SessionFactory.getCurrentSession() 来获取Session。它的过程大概是这样的, ?
? ? 2.1 ?SessionFactory.getCurrentSession() 会调用?JTASessionContext.currentSession();? ? ? ? 2.2 ?JTASessionContext 维护了一个 trasaction 跟 session 的 map。JTASessionContext.currentSession() 的逻辑是先 根据TractionManager 获取当前 tranction , 然后?来这个map 找对应的session 如果没有 就创建一个新的SessionImpl。? ? 2.3 ?在SessionImpl 建构函数中 会创建一个新的JDBCContext. 这个JDBCContext 名字比较悲催啊其实不管是JDBC 还是JTA 都是需要它的。 以前被它给忽悠了, 其实在JTA的环境下它的作用更大的说。在它的建构函数中 调用了一个 ?非常重要的方法?registerSynchronizationIfPossible。 ? ??public boolean registerSynchronizationIfPossible() {
?
这个方法 中的 ?owner.getFactory().getSettings().getTransactionFactory() ?就用到了三个配置参数中的最后一个?org.hibernate.transaction.CMTTransactionFactory 。 ?这个TransactionFactory 的?areCallbacksLocalToHibernateTransactions ?返回 false。 如果我们不配置这个参数??owner.getFactory().getSettings().getTransactionFactory()? 拿到的就是 JDBCTransactionFactory 了, ?它就当然不会走到后面的 ??? ? ? tx.registerSynchronization( new CacheSynchronization(owner, this, tx, hibernateTransaction) );
? ? ?这一行代码 会在JTA transaction 注册一个 Synchronization:CacheSynchronization。
? ?2.4 在CacheSynchronization 实现的?beforeCompletion 方法中 调用 sessionImpl.managedFlush() 方法。?
这样我们可以看到 JTA 下面 ?transaction 跟 session 是 一对一, 在transaction 结束的时候 flush , close session。 ?当然我们需要我们通过?JTASessionContext.currentSession()? 来保证 都是走 JTASessionContext 来管理 session。 ?