因爲項目中既用到了Hibernate,又用到了Mybatis,還用到了JdbcTemplate,比較糾結於他們的事務,抽了個時間好好研究了下,有理解不正確的地方,歡迎批評指正 web
大體的來講,事務能夠分爲如下2中: spring
1.JDBC的事務 數據庫
2.JTA,容器的事務 express
因爲不涉及到JTA,就不談JTA的事務了 session
TransactionManager用的是HibernateTransactionManager,大概配置以下: spa
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory"> <ref bean="sessionFactory" /> </property> </bean>
配置的事務是在service.impl層的,配置大概以下 hibernate
<aop:config> <aop:pointcut id="allManagerMethod" expression="execution(* com.xxx.web.*.service.impl.*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod" /> </aop:config>這樣的話只能在service.impl層拿到HibernateSession,若是在其它層調用會發生找不到session的異常,以上都比較好理解
問題是,如今在service.impl層又用到了Mybatis,還有JdbcTemplate,那麼他們的事務怎麼處理的?和hibernate的又有什麼關係? code
經試驗發現Mybatis和JdbcTemplate的事務也是受spring管控的,就是說若是調用2個更新數據庫的方法,第二個方法出異常了,則第一個方法也會回滾,以前還擔憂不能回滾的疑慮就消除了,能夠放心大膽的使用Mybatis和JdbcTemplate了,由於他們都是用的JDBC的事務,因此只有他們的數據源是同樣的就可讓spring來管理事務 orm
後來又作了個實驗 xml
不在service.impl層調用Mybatis的方法和JdbcTemplate的方也法是能夠的,可是沒有事務,即若是調用2個更新數據庫的方法,第二個方法出異常了,則第一個方法是不會回滾的
--------------------------------------------------------------分割線
又作了個實驗,換了下transactionManager,配置以下:
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean>即沒有用HibernateTransactionManager,發現對於JdbcTemplate的事務和之前同樣,即若是在service.impl層是受spring管控事務的,可是對於Hibernate,會出現拿不到session的異常,因此最佳實踐仍是用 HibernateTransactionManager