# 【第九章】 Spring的事務 之 9.2 事務管理器 ——跟我學spring3
### 9.2.1? 概述
Spring框架支持事務管理的核心是事務管理器抽象,對于不同的數據訪問框架(如Hibernate)通過實現策略接口PlatformTransactionManager,從而能支持各種數據訪問框架的事務管理,PlatformTransactionManager接口定義如下:
```
public interface PlatformTransactionManager {
TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
void commit(TransactionStatus status) throws TransactionException;
void rollback(TransactionStatus status) throws TransactionException;
}
```
* **getTransaction():**返回一個已經激活的事務或創建一個新的事務(根據給定的TransactionDefinition類型參數定義的事務屬性),返回的是TransactionStatus對象代表了當前事務的狀態,其中該方法拋出TransactionException(未檢查異常)表示事務由于某種原因失敗。
* **commit():**用于提交TransactionStatus參數代表的事務,具體語義請參考Spring Javadoc;
* **rollback():**用于回滾TransactionStatus參數代表的事務,具體語義請參考Spring Javadoc。
**TransactionDefinition接口定義如下:**
```
public interface TransactionDefinition {
int getPropagationBehavior();
int getIsolationLevel();
int getTimeout();
boolean isReadOnly();
String getName();
}
```
* **getPropagationBehavior():**返回定義的事務傳播行為;
* **getIsolationLevel():**返回定義的事務隔離級別;
* **getTimeout():**返回定義的事務超時時間;
* **isReadOnly():**返回定義的事務是否是只讀的;
* **getName():**返回定義的事務名字。
**TransactionStatus接口定義如下:**
```
public interface TransactionStatus extends SavepointManager {
boolean isNewTransaction();
boolean hasSavepoint();
void setRollbackOnly();
boolean isRollbackOnly();
void flush();
boolean isCompleted();
}
```
* **isNewTransaction():返回**當前事務狀態是否是新事務**;**
* **hasSavepoint():返回當前事務是否有保存點**;
* **setRollbackOnly():**設置當前事務應該回滾;
* **isRollbackOnly(():**返回當前事務是否應該回滾;
* **flush():**用于刷新底層會話中的修改到數據庫,一般用于刷新如Hibernate/JPA的會話,可能對如JDBC類型的事務無任何影響;
* **isCompleted():**當前事務否已經完成。
### 9.2.2?? ?內置事務管理器實現
Spring提供了許多內置事務管理器實現:
* **DataSourceTransactionManager:**位于org.springframework.jdbc.datasource包中,數據源事務管理器,提供對單個javax.sql.DataSource事務管理,用于Spring JDBC抽象框架、iBATIS或MyBatis框架的事務管理;
* **JdoTransactionManager:**位于org.springframework.orm.jdo包中,提供對單個javax.jdo.PersistenceManagerFactory事務管理,用于集成JDO框架時的事務管理;
* **JpaTransactionManager:**位于org.springframework.orm.jpa包中,提供對單個javax.persistence.EntityManagerFactory事務支持,用于集成JPA實現框架時的事務管理;
* **HibernateTransactionManager:**位于org.springframework.orm.hibernate3包中,提供對單個org.hibernate.SessionFactory事務支持,用于集成Hibernate框架時的事務管理;該事務管理器只支持Hibernate3+版本,且Spring3.0+版本只支持Hibernate 3.2+版本;
* **JtaTransactionManager:**位于org.springframework.transaction.jta包中,提供對分布式事務管理的支持,并將事務管理委托給Java EE應用服務器事務管理器;
* **OC4JjtaTransactionManager:**位于org.springframework.transaction.jta包中,Spring提供的對OC4J10.1.3+應用服務器事務管理器的適配器,此適配器用于對應用服務器提供的高級事務的支持;
* **WebSphereUowTransactionManager:**位于org.springframework.transaction.jta包中,Spring提供的對WebSphere 6.0+應用服務器事務管理器的適配器,此適配器用于對應用服務器提供的高級事務的支持;
* **WebLogicJtaTransactionManager:**位于org.springframework.transaction.jta包中,Spring提供的對WebLogic 8.1+應用服務器事務管理器的適配器,此適配器用于對應用服務器提供的高級事務的支持。
Spring不僅提供這些事務管理器,還提供對如JMS事務管理的管理器等,Spring提供一致的事務抽象如圖9-1所示。

圖9-1 Spring事務管理器
接下來讓我們學習一下如何在Spring配置文件中定義事務管理器:
**一、聲明對本地事務的支持:**
**a)JDBC及iBATIS、MyBatis框架事務管理器**
```
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
```
通過dataSource屬性指定需要事務管理的單個javax.sql.DataSource對象。
**b)Jdo事務管理器**
```
<bean id="txManager" class="org.springframework.orm.jdo.JdoTransactionManager">
<property name="persistenceManagerFactory" ref="persistenceManagerFactory"/>
</bean>
```
通過persistenceManagerFactory屬性指定需要事務管理的javax.jdo.PersistenceManagerFactory對象。
**c)Jpa事務管理器**
```
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
```
通過entityManagerFactory屬性指定需要事務管理的javax.persistence.EntityManagerFactory對象。
還需要為entityManagerFactory對象指定jpaDialect屬性,該屬性所對應的對象指定了如何獲取連接對象、開啟事務、關閉事務等事務管理相關的行為。
```
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
……
<property name="jpaDialect" ref="jpaDialect"/>
</bean>
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
```
**d)Hibernate事務管理器**
```
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
```
通過entityManagerFactory屬性指定需要事務管理的org.hibernate.SessionFactory對象。
**二、Spring對全局事務的支持:**
**a)Jta事務管理器**
```
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/test"/>
<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManagerName" value=" java:comp/TransactionManager"/>
</bean>
</beans>
```
“dataSource”Bean表示從JNDI中獲取的數據源,而txManager是JTA事務管理器,其中屬性transactionManagerName指定了JTA事務管理器的JNDI名字,從而將事務管理委托給該事務管理器。
這只是最簡單的配置方式,更復雜的形式請參考Spring Javadoc。
在此我們再介紹兩個不依賴于應用服務器的開源JTA事務實現:JOTM和Atomikos Transactions Essentials。
* **JOTM:**即基于Java開放事務管理器(Java Open Transaction Manager),實現JTA規范,能夠運行在非應用服務器環境中,Web容器或獨立Java SE環境,官網地址: http://jotm.objectweb.org/。
* **Atomikos Transactions Essentials:**其為Atomikos開發的事務管理器,該產品屬于開源產品,另外還一個商業的Extreme Transactions。官網地址為:http://www.atomikos.com。
對于以上JTA事務管理器使用,本文作者只是做演示使用,如果在實際項目中需要不依賴于應用服務器的JTA事務支持,需詳細測試并選擇合適的。
在本文中將使用Atomikos Transactions Essentials來進行演示JTA事務使用,由于Atomikos對hsqldb分布式支持不是很好,在Atomikos官網中列出如下兼容的數據庫:Oracle、Informix、FirstSQL、DB2、MySQL、SQLServer、Sybase,這不代表其他數據庫不支持,而是Atomikos團隊沒完全測試,在此作者決定使用derby內存數據庫來演示JTA分布式事務。
**1、首先準備jar包:**
**1.1、準備derby數據jar包,**到下載的spring-framework-3.0.5.RELEASE-dependencies.zip中拷貝如下jar包:
+ com.springsource.org.apache.derby-10.5.1000001.764942.jar
**1.2、準備Atomikos Transactions Essentials?對JTA事務支持的JTA包,**此處使用AtomikosTransactionsEssentials3.5.5版本,到官網下載AtomikosTransactionsEssentials-3.5.5.zip,拷貝如下jar包到類路徑:
+ atomikos-util.jar
+ transactions-api.jar
+ transactions-essentials-all.jar
+ transactions-jdbc.jar
+ transactions-jta.jar
+ transactions.jar
將如上jar包放在lib\atomikos目錄下,并添加到類路徑中。
**2、接下來看一下在Spring中如何配置AtomikosTransactionsEssentials JTA事務:**
**2.1、配置分布式數據源:**
```
<bean id="dataSource1" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
<property name="uniqueResourceName" value="jdbc/test1"/>
<property name="xaDataSourceClassName" value="org.apache.derby.jdbc.EmbeddedXADataSource"/>
<property name="poolSize" value="5"/>
<property name="xaProperties">
<props>
<prop key="databaseName">test1</prop>
<prop key="createDatabase">create</prop>
</props>
</property>
</bean>
<bean id="dataSource2" class="com.atomikos.jdbc.AtomikosDataSourceBean"
init-method="init" destroy-method="close">
……
</bean>
```
在此我們配置兩個分布式數據源:使用com.atomikos.jdbc.AtomikosDataSourceBean來配置AtomikosTransactionsEssentials分布式數據源:
* uniqueResourceName表示唯一資源名,如有多個數據源不可重復;
* xaDataSourceClassName是具體分布式數據源廠商實現;
* poolSize是數據連接池大小;
* xaProperties屬性指定具體廠商數據庫屬性,如databaseName指定數據庫名,createDatabase表示啟動derby內嵌數據庫時創建databaseName指定的數據庫。
在此我們還有定義了一個“dataSource2”Bean,其屬性和“DataSource1”除以下不一樣其他完全一樣:
* uniqueResourceName:因為不能重復,因此此處使用jdbc/test2;
* databaseName:我們需要指定兩個數據庫,因此此處我們指定為test2。
2.2、配置事務管理器:
```
<bean id="atomikosTransactionManager" class = "com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method = "close">
<property name="forceShutdown" value="true"/>
</bean>
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp"> </bean>
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager">
<ref bean="atomikosTransactionManager"/>
</property>
<property name="userTransaction">
<ref bean="atomikosUserTransaction"/>
</property>
</bean>
```
* atomikosTransactionManager:定義了AtomikosTransactionsEssentials事務管理器;
* atomikosUserTransaction:定義UserTransaction,該Bean是線程安全的;
* transactionManager:定義Spring事務管理器,transactionManager屬性指定外部事務管理器(真正的事務管理者),使用userTransaction指定UserTransaction,該屬性一般用于本地JTA實現,如果使用應用服務器事務管理器,該屬性將自動從JNDI獲取。
配置完畢,是不是也挺簡單的,但是如果確實需要使用JTA事務,請首先選擇應用服務器事務管理器,本示例不適合生產環境,如果非要運用到生產環境,可以考慮購買AtomikosTransactionsEssentials商業支持。
b)特定服務器事務管理器
Spring還提供了對特定應用服務器事務管理器集成的支持,目前提供對IBM WebSphere、BEA WebLogic、 Oracle OC4J應用服務器高級事務的支持,具體使用請參考Spring Javadoc。
現在我們已經學習如何配置事務管理器了,但是只有事務管理器Spring能自動進行事務管理嗎?當然不能了,這需要我們來控制,目前Spring支持兩種事務管理方式:編程式和聲明式事務管理。接下來先看一下如何進行編程式事務管理吧。
原創內容,轉載請注明出處【[http://sishuok.com/forum/blogPost/list/0/2503.html](http://sishuok.com/forum/blogPost/list/0/2503.html#7221)】
- 跟我學 Spring3
- 【第二章】 IoC 之 2.1 IoC基礎 ——跟我學Spring3
- 【第二章】 IoC 之 2.2 IoC 容器基本原理 ——跟我學Spring3
- 【第二章】 IoC 之 2.3 IoC的配置使用——跟我學Spring3
- 【第三章】 DI 之 3.1 DI的配置使用 ——跟我學spring3
- 【第三章】 DI 之 3.2 循環依賴 ——跟我學spring3
- 【第三章】 DI 之 3.3 更多DI的知識 ——跟我學spring3
- 【第三章】 DI 之 3.4 Bean的作用域 ——跟我學spring3
- 【第四章】 資源 之 4.1 基礎知識 ——跟我學spring3
- 【第四章】 資源 之 4.2 內置Resource實現 ——跟我學spring3
- 【第四章】 資源 之 4.3 訪問Resource ——跟我學spring3
- 【第四章】 資源 之 4.4 Resource通配符路徑 ——跟我學spring3
- 【第五章】Spring表達式語言 之 5.1 概述 5.2 SpEL基礎 ——跟我學spring3
- 【第五章】Spring表達式語言 之 5.3 SpEL語法 ——跟我學spring3
- 【第五章】Spring表達式語言 之 5.4在Bean定義中使用EL—跟我學spring3
- 【第六章】 AOP 之 6.1 AOP基礎 ——跟我學spring3
- 【第六章】 AOP 之 6.2 AOP的HelloWorld ——跟我學spring3
- 【第六章】 AOP 之 6.3 基于Schema的AOP ——跟我學spring3
- 【第六章】 AOP 之 6.4 基于@AspectJ的AOP ——跟我學spring3
- 【第六章】 AOP 之 6.5 AspectJ切入點語法詳解 ——跟我學spring3
- 【第六章】 AOP 之 6.6 通知參數 ——跟我學spring3
- 【第六章】 AOP 之 6.7 通知順序 ——跟我學spring3
- 【第六章】 AOP 之 6.8 切面實例化模型 ——跟我學spring3
- 【第六章】 AOP 之 6.9 代理機制 ——跟我學spring3
- 【第七章】 對JDBC的支持 之 7.1 概述 ——跟我學spring3
- 【第七章】 對JDBC的支持 之 7.2 JDBC模板類 ——跟我學spring3
- 【第七章】 對JDBC的支持 之 7.3 關系數據庫操作對象化 ——跟我學spring3
- 【第七章】 對JDBC的支持 之 7.4 Spring提供的其它幫助 ——跟我學spring3【私塾在線原創】
- 【第七章】 對JDBC的支持 之 7.5 集成Spring JDBC及最佳實踐 ——跟我學spring3
- 【第八章】 對ORM的支持 之 8.1 概述 ——跟我學spring3
- 【第八章】 對ORM的支持 之 8.2 集成Hibernate3 ——跟我學spring3
- 【第八章】 對ORM的支持 之 8.3 集成iBATIS ——跟我學spring3
- 【第八章】 對ORM的支持 之 8.4 集成JPA ——跟我學spring3
- 【第九章】 Spring的事務 之 9.1 數據庫事務概述 ——跟我學spring3
- 【第九章】 Spring的事務 之 9.2 事務管理器 ——跟我學spring3
- 【第九章】 Spring的事務 之 9.3 編程式事務 ——跟我學spring3
- 【第九章】 Spring的事務 之 9.4 聲明式事務 ——跟我學spring3
- 【第十章】集成其它Web框架 之 10.1 概述 ——跟我學spring3
- 【第十章】集成其它Web框架 之 10.2 集成Struts1.x ——跟我學spring3
- 【第十章】集成其它Web框架 之 10.3 集成Struts2.x ——跟我學spring3
- 【第十章】集成其它Web框架 之 10.4 集成JSF ——跟我學spring3
- 【第十一章】 SSH集成開發積分商城 之 11.1 概述 ——跟我學spring3
- 【第十一章】 SSH集成開發積分商城 之 11.2 實現通用層 ——跟我學spring3
- 【第十一章】 SSH集成開發積分商城 之 11.3 實現積分商城層 ——跟我學spring3
- 【第十二章】零配置 之 12.1 概述 ——跟我學spring3
- 【第十二章】零配置 之 12.2 注解實現Bean依賴注入 ——跟我學spring3
- 【第十二章】零配置 之 12.3 注解實現Bean定義 ——跟我學spring3
- 【第十二章】零配置 之 12.4 基于Java類定義Bean配置元數據 ——跟我學spring3
- 【第十二章】零配置 之 12.5 綜合示例-積分商城 ——跟我學spring3
- 【第十三章】 測試 之 13.1 概述 13.2 單元測試 ——跟我學spring3
- 【第十三章】 測試 之 13.3 集成測試 ——跟我學spring3
- 跟我學 Spring MVC
- SpringMVC + spring3.1.1 + hibernate4.1.0 集成及常見問題總結
- Spring Web MVC中的頁面緩存支持 ——跟我學SpringMVC系列
- Spring3 Web MVC下的數據類型轉換(第一篇)——《跟我學Spring3 Web MVC》搶先看
- Spring3 Web MVC下的數據格式化(第二篇)——《跟我學Spring3 Web MVC》搶先看
- 第一章 Web MVC簡介 —— 跟開濤學SpringMVC
- 第二章 Spring MVC入門 —— 跟開濤學SpringMVC
- 第三章 DispatcherServlet詳解 ——跟開濤學SpringMVC
- 第四章 Controller接口控制器詳解(1)——跟著開濤學SpringMVC
- 第四章 Controller接口控制器詳解(2)——跟著開濤學SpringMVC
- 第四章 Controller接口控制器詳解(3)——跟著開濤學SpringMVC
- 第四章 Controller接口控制器詳解 (4)——跟著開濤學SpringMVC
- 第四章 Controller接口控制器詳解(5)——跟著開濤學SpringMVC
- 跟著開濤學SpringMVC 第一章源代碼下載
- 第二章 Spring MVC入門 源代碼下載
- 第四章 Controller接口控制器詳解 源代碼下載
- 第四章 Controller接口控制器詳解(6)——跟著開濤學SpringMVC
- 第四章 Controller接口控制器詳解(7 完)——跟著開濤學SpringMVC
- 第五章 處理器攔截器詳解——跟著開濤學SpringMVC
- 源代碼下載 第五章 處理器攔截器詳解——跟著開濤學SpringMVC
- 注解式控制器運行流程及處理器定義 第六章 注解式控制器詳解——跟著開濤學SpringMVC
- 源代碼下載 第六章 注解式控制器詳解
- SpringMVC3強大的請求映射規則詳解 第六章 注解式控制器詳解——跟著開濤學SpringMVC
- Spring MVC 3.1新特性 生產者、消費者請求限定 —— 第六章 注解式控制器詳解——跟著開濤學SpringMVC
- SpringMVC強大的數據綁定(1)——第六章 注解式控制器詳解——跟著開濤學SpringMVC
- SpringMVC強大的數據綁定(2)——第六章 注解式控制器詳解——跟著開濤學SpringMVC
- SpringMVC數據類型轉換——第七章 注解式控制器的數據驗證、類型轉換及格式化——跟著開濤學SpringMVC
- SpringMVC數據格式化——第七章 注解式控制器的數據驗證、類型轉換及格式化——跟著開濤學SpringMVC
- SpringMVC數據驗證——第七章 注解式控制器的數據驗證、類型轉換及格式化——跟著開濤學SpringMVC