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() {
if ( isTransactionCallbackRegistered ) {
// we already have a callback registered; either a local
// (org.hibernate.Transaction) transaction has accepted
// callback responsibilities, or we have previously
// registered a transaction synch.
return true;
}
boolean localCallbacksOnly = owner.getFactory().getSettings()
.getTransactionFactory()
.areCallbacksLocalToHibernateTransactions();
if ( localCallbacksOnly ) {
// the configured transaction-factory says it only supports
// local callback mode, so no sense attempting to register a
// JTA Synchronization
return false;
}
TransactionManager tm = owner.getFactory().getTransactionManager();
if ( tm == null ) {
// if there is no TM configured, we will not be able to access
// the javax.transaction.Transaction object in order to
// register a synch anyway.
return false;
}
else {
try {
if ( !isTransactionInProgress() ) {
log.trace( "TransactionFactory reported no active transaction; Synchronization not registered" );
return false;
}
else {
javax.transaction.Transaction tx = tm.getTransaction();
if ( JTAHelper.isMarkedForRollback( tx ) ) {
// transactions marked for rollback-only cause some TM impls to throw exceptions
log.debug( "Transaction is marked for rollback; skipping Synchronization registration" );
return false;
}
else {
if ( hibernateTransaction == null ) {
hibernateTransaction = owner.getFactory().getSettings().getTransactionFactory().createTransaction( this, owner );
}
tx.registerSynchronization( new CacheSynchronization(owner, this, tx, hibernateTransaction) );
isTransactionCallbackRegistered = true;
log.debug("successfully registered Synchronization");
return true;
}
}
}
catch( HibernateException e ) {
throw e;
}
catch (Exception e) {
throw new TransactionException( "could not register synchronization with JTA TransactionManager", e );
}
}
}
这个方法 中的 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。
分享到:
相关推荐
Wicket6.7 Spring3.2 Hibernate4.2 EJB全注解实例.采用JTA事务管理,配置ehcache为二级缓存,在glassfish3.2.2和postgresql9测试通过。参考网上的资料整理。
Wicket6.0_Spring3.1_Hibernate4.1_EJB全注解实例。采用JTA事务管理,在glassfish3.1.2和postgresql9测试通过。参考网上的资料整理。
spring版本有2.0,2.5的,hibernate版本较多些至3.2,首先选版本就选择最优的,struts2没的选只有2.1.6版的,所以先导入struts2支持,然后是spring选的是2.0,问题就出在struts2中spring的插件上了,没有从MyEclipse...
9.5 在EJB组件中使用Java Persistence 9.5.1 注入EntityManager 9.5.2 查找EntityManager 9.5.3 访问EntityManagerFactory 9.6 小结 第10章 事务和并发 10.1 事务本质 10.1.1 数据库...
25.2 在业务代理类中访问EJB组件 25.3 发布J2EE应用 25.3.1 在JBoss上部署EJB组件 25.3.2 在JBoss上部署Web应用 25.3.3 在JBoss上部署J2EE应用 25.4 小结 附录A 标准SQL语言的用法 A.1 数据...
ejb3-persistence.jar、hibernate3.jar、hibernate-annotations.jar hibernate-commons-annotations.jar、hibernate-jpa-2.0-api-1.0.1.Final.jar、javassist-3.9.0.GA.jar、jta-1.1.jar、 slf4j-api-1.5.8.jar、slf...
2.7.6.jar、commons-collections-3.1.jar、commons-logging-1.1.3.jar、dom4j-1.6.1.jar、ejb3-persistence.jar、hibernate3.jar、hibernate-jpa-2.0-api-1.0.1.Final.jar、javassist-3.12.0.GA.jar、jta-...
4.ejb3-persistence.jar ; 5.hibernate3.jar ; 6.hibernate-annotations.jar ; 7.hibernate-commons-annotations-5.0.1.Final.jar ; 8.javassist-3.12.0.GA.jar ; 9.jta-1.1.jar ; 10.slf4j-api-1.6.1.jar ; 11.slf...
7.3.1 在WebLogic中配置JavaMail 288 7.3.2 通过WebLogic的邮件支持来 发送邮件 290 7.3.3 在JBoss中配置JavaMail 292 7.4 本章小结 294 第8章 会话EJB 295 8.1 EJB概述 296 8.1.1 EJB的概念和意义 296 8.1.2 EJB的...
25.2 在业务代理类中访问EJB组件 25.3 发布J2EE应用 25.3.1 在JBoss上部署EJB组件 25.3.2 在JBoss上部署Web应用 25.3.3 在JBoss上部署J2EE应用 25.4 小结 附录A 标准SQL语言的用法 A.1 数据...
25.2 在业务代理类中访问EJB组件 25.3 发布J2EE应用 25.3.1 在JBoss上部署EJB组件 25.3.2 在JBoss上部署Web应用 25.3.3 在JBoss上部署J2EE应用 25.4 小结 附录A 标准SQL语言的用法 A.1 数据...
25.2 在业务代理类中访问EJB组件 25.3 发布J2EE应用 25.3.1 在JBoss上部署EJB组件 25.3.2 在JBoss上部署Web应用 25.3.3 在JBoss上部署J2EE应用 25.4 小结 附录A 标准SQL语言的用法 A.1 数据...
6.3.6 在代码中使用Log4j 6.4 改进Log4j 6.5 小结 第七章 Ant使用指南 7.1 Ant介绍 7.1.1 Ant简介 7.1.2 为什么要使用Ant 7.2 建立Ant的开发环境 7.2.1 下载Ant 7.2.2 配置Ant 7.3 Ant的使用方法 7.3.1 Ant能完成的...
6.3.6 在代码中使用Log4j 6.4 改进Log4j 6.5 小结 第七章 Ant使用指南 7.1 Ant介绍 7.1.1 Ant简介 7.1.2 为什么要使用Ant 7.2 建立Ant的开发环境 7.2.1 下载Ant 7.2.2 配置Ant 7.3 Ant的使用方法 7.3.1 Ant能完成的...
antlr-2.7.6.jar ...ejb3-persistence.jar hibernate3.jar hibernate-annotations.jar hibernate-commons-annotations.jar javassist-3.9.0.GA.jar jta-1.1.jar slf4j-api-1.5.8.jar slf4j-nop-1.5.8.jar
antlr-2.7.6 commons-collections-3.1 dom4j-1.6.1 ejb3-persistence hibernate3 hibernate-annotations hibernate-commons-annotations javassist-3.9.0.GA jta-1.1 mysql-connector-java-5.0.8-bin slf4j-api-...
6.3.6 在代码中使用Log4j 6.4 改进Log4j 6.5 小结 第七章 Ant使用指南 7.1 Ant介绍 7.1.1 Ant简介 7.1.2 为什么要使用Ant 7.2 建立Ant的开发环境 7.2.1 下载Ant 7.2.2 配置Ant 7.3 Ant的使用方法 7.3.1 Ant能完成的...
hibernate开发用到的jar包,里面有antlr-2.7.6.jar、commons-collections-3.1.jar、dom4j-1.6.jar、ejb3-persistence.jar、hibernate3.jar、hibernate-annotations.jar\hibernate-commons-annotations.jar\javassist...
Hibernate3.6.10用到的jiar antlr-2.7.6.jar,commons-collections-3.1, commons-logging-1.1.3, dom4j-1.6.1, ejb3-persistence, hibernate-jpa-2.0-api-1.0.1.Final, hibernate3, javassist-3.12.0.GA, jta-...