HibernateTransactionManager和DataSourceTransactionManager

转载 2016年05月30日 17:45:05

spring中常用的事务管理有DataSourceTransactionManager 和HibernateTransactionManager,他们服务的对象不同,下面来简单说明一下:

1、DataSourceTransactionManager:此事务管理器是针对传统的JDBC进行事务管理,在spring中是对JdbcTemplate进行事务管理

2、HibernateTransactionManager:是对Hibernate进行事务管理,当在spring中使用HibernateTemplate时,要使用此管理器。

但是当在service的一个方法中同时使用了JdbcTemplate和HibernateTemplate时,就要使用HibernateTransactionManager了,因为当使用DataSourceTransactionManager时,JdbcTemplate和HibernateTemplate获得的connection并不是同一个,也就没办法对service的方法进行事务管理了。

如果一个方法中既用了HibernateTemplate,又用了JdbcTemplate,应该怎么配单实例的db事务呢(多例免谈)用 DataSouceTransactionManager是不行的,而用HibernateTransactionManager就可以保证 
原因的话看下它们源代码,会发现HibernateTransactionManager中的处理可以保证SessionFactoryUtil和datasourceutil都能在一个事务里取到同一个连接 

原文如下===================================================================== 

今天这边报出一个问题,他在一个service方法里面,用了jdbcdaosupport的dao又用了hibernateDaoSupport的dao,在spring里面给service方法配上了事务, 

但是通过mysql的bin log,发现这种不同的dao使用的连接id不是同一个,即jdbctemplate使用了一个链接,而hibernatetemplate使用了另外一个链接,这样虽然两种dao都是针对一个mysql实例,但却没法保证事务。 

之前xd提过使用hibernateTransaction manager,可以保证混用时候的事务,但是却不知道为啥会这样。我们这边就以为datasourcetransactionmanager也是一样,但发现事实上不一样。确实我们换成hibernateTransaction manager,两种dao使用的connection就归一了,真好,但是为啥呢? 

翻了半天spring的源代码终于找到了。 

以下是datasourceTransactionManager的doGetTransaction和doBegin代码 

Java代码  收藏代码
  1. protected Object doGetTransaction() {  
  2.   
  3. //只是设定一个dataSource为key的存放connection的threadlcal  
  4.    DataSourceTransactionObject txObject = new DataSourceTransactionObject();  
  5.    txObject.setSavepointAllowed(isNestedTransactionAllowed());  
  6.    ConnectionHolder conHolder =  
  7.       (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);  
  8.    txObject.setConnectionHolder(conHolder, false);  
  9.    return txObject;  
  10. }  
  11.   
  12. protected void doBegin(Object transaction, TransactionDefinition definition) {  
  13.      .....  
  14.   
  15.    try {  
  16.     if (txObject.getConnectionHolder() == null ||  
  17.       txObject.getConnectionHolder().isSynchronizedWithTransaction()) {  
  18.      Connection newCon = this.dataSource.getConnection();  
  19.     }  
  20.   
  21. ....  
  22. //从datasource拿一个连接,放入thread生命周期的holder  
  23.   
  24. }  


这就完了。 

然后jdbctemplate会通过datasourceutil去拿这个holder里面的connection 

从而在一个事务里使用这个连接。 

但是hibernateTransactionManager呢: 

Java代码  收藏代码
  1. protected Object doGetTransaction() {  
  2.    HibernateTransactionObject txObject = new HibernateTransactionObject();  
  3.    txObject.setSavepointAllowed(isNestedTransactionAllowed());  
  4.   
  5.    SessionHolder sessionHolder =  
  6.      (SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory());  
  7.    if (sessionHolder != null) {  
  8.     if (logger.isDebugEnabled()) {  
  9.      logger.debug("Found thread-bound Session [" +  
  10.        SessionFactoryUtils.toString(sessionHolder.getSession()) + "] for Hibernate transaction");  
  11.     }  
  12.     txObject.setSessionHolder(sessionHolder, false);  
  13.    }  
  14.   
  15.    if (getDataSource() != null) {  
  16.     ConnectionHolder conHolder = (ConnectionHolder)  
  17.       TransactionSynchronizationManager.getResource(getDataSource());  
  18.     txObject.setConnectionHolder(conHolder);  
  19.    }  
  20.   
  21.    return txObject;  
  22. }  
  23.   
  24. //两个holder都管!  
  25.   
  26. protected void doBegin(Object transaction, TransactionDefinition definition) {  
  27.      .....  
  28.   
  29.    try {  
  30.     if (txObject.getSessionHolder() == null || txObject.getSessionHolder().isSynchronizedWithTransaction()) {  
  31.      Interceptor entityInterceptor = getEntityInterceptor();  
  32.      Session newSession = (entityInterceptor != null ?  
  33.        getSessionFactory().openSession(entityInterceptor) : getSessionFactory().openSession());  
  34.      if (logger.isDebugEnabled()) {  
  35.       logger.debug("Opened new Session [" + SessionFactoryUtils.toString(newSession) +  
  36.         "] for Hibernate transaction");  
  37.      }  
  38.      txObject.setSessionHolder(new SessionHolder(newSession), true);  
  39.     }  
  40.   
  41.     .....  
  42.     //从sessionFactory拿个新session,也会产生一个新连接  
  43.   
  44.     session = txObject.getSessionHolder().getSession();  
  45.   
  46.     if (this.prepareConnection && isSameConnectionForEntireSession(session)) {  
  47.      // We're allowed to change the transaction settings of the JDBC Connection.  
  48.      if (logger.isDebugEnabled()) {  
  49.       logger.debug(  
  50.         "Preparing JDBC Connection of Hibernate Session [" + SessionFactoryUtils.toString(session) + "]");  
  51.      }  
  52.   
  53.      //原来直接把session后面的connection也放入holder  
  54.      Connection con = session.connection();  
  55.      Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);  
  56.      txObject.setPreviousIsolationLevel(previousIsolationLevel);  
  57.     }  

所以如果使用hibernateTransactionManager的话,就完全可以保证SessionFactoryUtil和datasourceutil都能在一个事务里取到同一个连接!所有的疑问烟消云散了, 
所以大家还是使用hibernateTransactionManager从而随心所欲的使用jdbctemplate和hibernatetemplate吧

原文来自:http://www.pinhuba.com/spring/101108.htm

http://bjyzxxds.iteye.com/blog/427309


相关文章推荐

事务管理(DataSourceTransactionManager,HibernateTransactionManger,JTATransactionManager)

autoProxyCreator 自动代理 1、传统使用JDBC的事务管理   以往使用JDBC进行数据操作,使用DataSource,从数据源中得到Connection,我们知道数据源是...

spring事务管理源码分析

闲来无事,重新看了下spring事务管理源码,写个笔记。 1、TransactionTemplate 当需要在事务中执行一个DB操作时,执行: transactionTemplate.exec...

spring事务管理器的源码和理解

原文出处: xieyu_zy http://www.importnew.com/19455.html 以前说了大多的原理,今天来说下spring的事务管理器的实现过程,顺带源码干货带上。 其实...
  • bluetjs
  • bluetjs
  • 2016年08月15日 19:55
  • 1020

Spring+Hibernate多数据源整合

在一个项目中,可能用到不止一个数据库,这个时候就需要用Hibernate配置多数据源 接上一篇文章:此处在上一篇文章中做一些修改 第一步:修改applicationContext.xml文件、配置...

HibernateTransactionManager 事务管理实现

HibernateTransactionManager对事务的实现,最终都是通过处理hibernate的Transaction的commit,rollback方法完成,   与单独的hibern...

Hibernate Session & Transaction详解

HIbernate中的Session   Session是JAVA应用程序和Hibernate进行交互时使用的主要接口,它也是持久化操作核心API,    注意这里的Session的含义,它与传统...

HibernateTransactionManager管理事务

如果一个方法中既用了HibernateTemplate,又用了JdbcTemplate,应该怎么配单实例的db事务呢(多例免谈)用 DataSouceTransactionManager是不行的,而用...
  • wo240
  • wo240
  • 2014年09月20日 19:53
  • 412

Spring事务管理之HibernateTransactionManager

对于Spring的事务管理,我们一般只知道是采用AOP(面向切面)的方式进行事务管理。也就是说,在执行Service方法时,Spring会通过动态代理的方式去获取执行service方法的对象,然后在执...

HibernateTransactionManager事物管理

如果一个方法中既用了HibernateTemplate,又用了JdbcTemplate,应该怎么配单实例的db事务呢(多例免谈)用 DataSouceTransactionManager是不行的,而用...
  • wo240
  • wo240
  • 2014年09月20日 19:55
  • 251

spring数据源的注入、JdbcTemplate管理、编程式的事务管理DataSourceTransactionManager

spring数据源的注入、JdbcTemplate管理、编程式的事务管理DataSourceTransactionManager 2010-06-14 22:00 对于不同的数据库...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HibernateTransactionManager和DataSourceTransactionManager
举报原因:
原因补充:

(最多只允许输入30个字)