Spring事務管理
該文章大多內容摘抄自《spring實戰:第三版》
一.spring對事務管理的支持
spring提供了對編碼式和聲明式事務管理的支持
編碼式事務允許用戶在代碼中精確定義事務的邊界,而聲明式事務(基于AOP)有助于用戶將操作與事務規則進行解耦,但是聲明式事務只能在方法級別聲明事務的邊界。
二.事務管理器
spring不直接管理事務,而是提供了多種事務管理器。每個事務管理器都會充當某一特定平臺的事務實現的門面。這使得用戶在spring中使用事務時,幾乎不用關心實際的事務實現是什么。
spring的事務管理器將事務管理的職責委托給特定的平臺的事務實現
事務管理器(org.framework.*) |
使用場景 |
jca.cci.connection.CciLocalTransactionManager |
使用Spring對Java EE連接器架構(Java EE Connector Architecture,JCA)和通用客戶端接口(Common Client Interface,CCI)提供支持 |
jdbc.datasource.DataSourceTransactionManager |
用Spring對JDBC抽象的支持,也可用于使用iBATIS進行持久化的場景 |
jms.connection.JmsTransactionManager |
用于JMS 1.1+ |
jms.connection.JmsTransactionManager102 |
用于JMS 1.0.2 |
orm.hibernate3.HibernateTransactionManager |
用于Hibernate3進行持久化 |
orm.jdo.JdoTransactionManager |
用于JDO進行持久化 |
orm.joa.JpaTransactionManager |
用于Java持久化 API進行持久化 |
transaction.jta.JtaTransactionManager |
需要分布式事務或者沒有其他的事務管理器滿足需求 |
transaction.jta.OC4JJtaTransactionManager |
用于Oracle的OC4J JEE容器 |
transaction.jta.WebLogicJtaTransactionManager |
需要使用分布式事務并且應用程序運行于WebLogic中 |
transaction.jta.WebSphereUowTransactionManager |
需要WebSphere中UOWManager所管理的事務 |
三.聲明式事務
1.定義事務屬性
在spring中聲明式事務是通過事務屬性來定義的。事務屬性描述了事務策略如何應用到方法上。
a.傳播行為
事務傳播行為用來描述由某一個事務傳播行為修飾的方法被嵌套進另一個方法時事務如何傳播。
b.隔離級別
隔離級別定義了一個事務可能受其他并發事務影響的程度。
多個事務并發運行,可能會導致以下問題:臟讀、不可重復讀、幻讀
隔離級別 |
含義 |
ISOLATION_DEFAULT |
使用后端數據庫默認的隔離級別。 |
ISOLATION_READ_UNCOMMITTED |
允許讀取尚未提交的更改。可能導致臟讀、幻影讀或不可重復讀。 |
ISOLATION_READ_COMMITTED |
允許從已經提交的并發事務讀取。可防止臟讀,但幻影讀和不可重復讀仍可能會發生。 |
ISOLATION_REPEATABLE_READ |
對相同字段的多次讀取的結果是一致的,除非數據被當前事務本身改變。可防止臟讀和不可重復讀,但幻影讀仍可能發生。 |
ISOLATION_SERIALIZABLE |
完全服從ACID的隔離級別,確保不發生臟讀、不可重復讀和幻影讀。這在所有隔離級別中也是最慢的,因為它通常是通過完全鎖定當前事務所涉及的數據表來完成的。 |
以上表格描述的隔離級別都在org.springframework.transaction.TransactionDefinition接口中已常量的方式進行了定義。但是不是所有的數據源都支持上表所列的隔離級別。
c.只讀
聲明式事務的第三個特性是它是否是一個只讀事務。如果一個事務只對后端數據庫執行讀操作,那么該數據庫就可能利用那個事務的只讀特性,采取某些優化 措施。通過把一個事務聲明為只讀,可以給后端數據庫一個機會來應用那些它認為合適的優化措施。由于只讀的優化措施是在一個事務啟動時由后端數據庫實施的, 因此,只有對于那些具有可能啟動一個新事務的傳播行為(PROPAGATION_REQUIRES_NEW、PROPAGATION_REQUIRED、 ROPAGATION_NESTED)的方法來說,將事務聲明為只讀才有意義。
此外,如果使用Hibernate作為持久化機制,那么把一個事務聲明為只讀,將使Hibernate的flush模式被設置為FLUSH_NEVER。這就告訴Hibernate避免和數據庫進行不必要的對象同步,從而把所有更新延遲到事務的結束。
d.事務超時
為了使一個應用程序很好地執行,它的事務不能運行太長時間。因此,聲明式事務的下一個特性就是它的超時。
假設事務的運行時間變得格外的長,由于事務可能涉及對后端數據庫的鎖定,所以長時間運行的事務會不必要地占用數據庫資源。這時就可以聲明一個事務在特定秒數后自動回滾,不必等它自己結束。
由于超時時鐘在一個事務啟動的時候開始的,因此,只有對于那些具有可能啟動一個新事務的傳播行為(PROPAGATION_REQUIRES_NEW、PROPAGATION_REQUIRED、ROPAGATION_NESTED)的方法來說,聲明事務超時才有意義。
d.回滾規則
事務五邊形的對后一個邊是一組規則,它們定義哪些異常引起回滾,哪些不引起。在默認設置下,事務只在出現運行時異常(runtime exception)時回滾,而在出現受檢查異常(checked exception)時不回滾(這一行為和EJB中的回滾行為是一致的)。
不過,也可以聲明在出現特定受檢查異常時像運行時異常一樣回滾。同樣,也可以聲明一個事務在出現特定的異常時不回滾,即使那些異常是運行時一場。
2.在XML中定義事務
Spring 提供了一個 tx 配置命名空間,借助它可以極大地簡化 Spring 中的聲明式事務。 這個 tx 命名空間提供了一些新的 XML 配置元素,其中,<tx:advice> 用于聲明事務性策略。
<tx:advice id="txAdvice" transaction-manager="配置好的事務管理器">
<tx:attributes>
<!-- 聲明名稱以 save 開頭的方法需要事務 -->
<tx:method name="save*" propagation="REQUIRED"/>
<!-- 其他方法聲明如果存在當前事務,它們將會在事務中運行,但是它們并不要求必須在事務中運行 -->
<tx:method name="*" propagation="SUPPORTS" read-only="true"/>
</tx:attributes>
</tx:advice>
對于<tx:advice>來說,事務屬性定義在<tx:attributes>元素中,該元素包含了一個或多個的<tx:method>元素。<tx:method>元素為某個(或某些)name 屬性(使用通配符)指定的方法定義事務參數。
<tx:method>有多個屬性來幫助定義方法的事務策略,對應了5個事務屬性
屬性 |
含義 |
isolation |
指定事務的隔離級別 |
propagation |
定義事務的傳播規則 |
read-only |
指定事務的只讀 |
回滾規則: rollback-for no-rollback-for |
指定事務對于哪些檢查型異常應當回滾而不提交 / 指定事務對于哪些異常應當繼續運行而不回滾 |
timeout |
對于長時間運行的事務定義超時時間 |
<tx:advice>只是定義了 AOP 通知,用于把事務的邊界通知給方法。為了完整定義事務性切面,我們必須定義一個通知器(advisor)。這就涉及 aop 命名空間了。
以下的 XML 定義了一個通知器:
<!-- 使用 txAdvice 通知所有實現 SpitterService 接口的 Bean -->
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* *..SpitterService.*(..))"/>
</aop:config>
3.定義注解驅動的事務
除了<tx:advice>元素,tx 命名空間還提供了<tx:annotation-driven> 元素。使用<tx:annotation-driven />時,通常只需要一行 XML。
<tx:annotation-driven> 元素告訴 Spring 檢查上下文中所有的 Bean 并查找使用 @Transactional 注解的 Bean,而不管這個注解是用在類級別上還是方法級別上。
我們可以通過 transaction-manager 屬性來指定特定的事務管理器(不配置默認值為 transactionManager)
<tx:annotation-driven>一共有四個屬性如下:
mode:指定Spring事務管理框架創建通知bean的方式。可用的值有proxy和aspectj。前者是默認值,表示通知對象是個JDK代理;后者表示Spring AOP會使用AspectJ創建代理
-
proxy-target-class:如果為true,Spring將創建子類來代理業務類(需要cglib庫);如果為false,則使用基于接口的代理。(如果使用子類代理,需要在類路徑中添加CGLib.jar類庫)
-
order:如果業務類除事務切面外,還需要織入其他的切面,通過該屬性可以控制事務切面在目標連接點的織入順序。
-
transaction-manager:指定到現有的PlatformTransaction Manager bean的引用,通知會使用該引用
@Transactional
對于每一個使用 @Transactional 注解的 Bean,<tx:annotation-driven> 會自動為它添加事務通知。通知的事務屬性是通過 @Transactional 注解的參數來定義的。
屬性 |
類型 |
描述 |
value |
String |
可選的限定描述符,指定使用的事務管理器 |
propagation |
enum: Propagation |
可選的事務傳播行為設置 |
isolation |
enum: Isolation |
可選的事務隔離級別設置 |
readOnly |
boolean |
讀寫或只讀事務,默認讀寫 |
timeout |
int (in seconds granularity) |
事務超時時間設置 |
rollbackFor |
Class對象數組,必須繼承自Throwable |
導致事務回滾的異常類數組 |
rollbackForClassName |
類名數組,必須繼承自Throwable |
導致事務回滾的異常類名字數組 |
noRollbackFor |
Class對象數組,必須繼承自Throwable |
不會導致事務回滾的異常類數組 |
noRollbackForClassName |
類名數組,必須繼承自Throwable |
不會導致事務回滾的異常類名字數組 |
@Transactional注意事項:
1.@Transactional 可以作用于接口、接口方法、類以及類方法上。但是Spring 建議不要在接口或者接口方法上使用該注解,因為這只有在使用基于接口的代理時它才會生效。
2.當作用于類上時,該類的所有 public 方法將都具有該類型的事務屬性,同時,我們也可以在方法級別使用該標注來覆蓋類級別的定義。
3.@Transactional 注解應該只被應用到 public 方法上,這是由 Spring AOP 的本質決定的。如果你在 protected、private 或者默認可見性的方法上使用 @Transactional 注解,這將被忽略,也不會拋出任何異常。
4. 默認情況下,只有來自外部的方法調用才會被AOP代理捕獲,也就是,類內部方法調用本類內部的其他方法并不會引起事務行為,即使被調用方法使用@Transactional注解進行修飾。
智能推薦
Spring 事務管理
案例—轉賬操作 創建一個關于轉賬的帳戶表 創建service與dao 對于數據的操作使用spring jdbc template Service層和Dao層代碼 Dao接口 Dao實現類 Service接口 Service實現類 測試類 service與dao的配置 數據庫配置文件db.properties 我們讓dao去extends JdbcDaoSupport類,這個類中它創建了...
Spring 事務管理
1.事務(編程式事務)(聲明式事務) 1.什么是事務? 把一組業務當做一個事務來做,要么成功,要么失敗!事務在項目開發中,十分重要,涉及到數據的一致性問題和完整性 2.事務ACID原則 原子性 一致性 隔離性:多個可能操作同一個資源,防止數據損壞 持久性:事務一旦提交,無論系統發生什么問題,結果都不會被影響,被持久化的寫到存儲器中 2 Spring中的事務管理 聲明式事務:AOP 編程式事務:需要...
Spring 事務管理
事務管理接口 編程式事務管理(基于Java編程控制,很少使用) 利用TransactionTemplate將多個DAO操作封裝起來 聲明式事務管理(基于Spring的AOP配置控制) 基于TransactionProxyFactoryBean的方式.(很少使用) 需要為每個進行事務管理的類,配置一個Transa...
Spring 事務管理
一、spring的事務管理 1.事物的概念: 事務管理是企業級應用程序開發中必不可少的技術, 用來確保數據的完整性和一致性。 事務就是一系列的動作, 它們被當作一個單獨的工作單元. 這些動作要么全部完成, 要么全部不起作用。 2.事務的屬性 事務的4個屬性:原子性、一致性、隔離性、持久性。這四個屬性通常稱為ACID特性。 原子性(atomicity): 事務是一個原子操作, 由一系列動作組成. 事...
Spring 事務管理
事務實現方式 在Spring中,事務有兩種實現方式,分別是編程式事務管理和聲明式事務管理兩種方式。 編程式事務管理: 編程式事務管理使用TransactionTemplate或者直接使用底層的PlatformTransactionManager。對于編程式事務管理,spring推薦使用TransactionTemplate。 聲明式事務管理: 建立在AOP之上的。其本質是對方法前后進行攔截,然后在...
猜你喜歡
Spring事務管理
事務 就是把一系列的動作當成一個獨立的工作單元,這些動作要么全部完成,要么全部不起作用。 事務四個屬性ACID 原子性(atomicity) 事務是原子性操作,由一系列動作組成,事務的原子性確保動作要么全部完成,要么完全不起作用 一致性(consistency) 一旦所有事務動作完成,事務就要被提交。數據和資源處于一種滿足業務規則的一致性狀態中 隔離性(isolation) 可能多個事務會同時處理...
Spring:事務管理
文章目錄 2、事務管理 1、事務的隔離級別? 1、事務概念 2、事務的四大特性 3、事務的隔離級別 2、Spring 事務的傳播行為? 1、接口介紹 2、事務的傳播特性 3、Spring業務層不使用事務 4、Spring編程式事務 5、Spring聲明式事務 1、基于TransactionProxyFactoryBean的方式 2、基于Aspetj的xml方式 3、基于注解的方式 2、事務管理 1...
spring事務管理
spring事務管理的兩種方式 第一種,編程式事務管理 第二種,聲明式事務管理 基于xml配置文件實現 基于注解實現 spring事務管理的api 接口:PlatformTransactionManager事務管理器 - 針對不同的dao層的框架,提供了這個接口不同的實現類 - 首先要配置事務管理器 轉賬案例 dao層 service層: 如果沒有事務管理,a賬戶余額減少,但是b賬戶余額并沒有增加...
Spring 事務管理
事務的定義 事務是一個操作集合,這些操作要么都執行,要么都不執行,它是一個不可分割的工作單位。 事務的特性 在一個事務性操作的環境下,操作有著以下的4種特性,被稱為ACID特性: 原子性(Atomicity):當事務結束,它對所有資源狀態的改變都被視為一個操作,這些操作要不同時成功,要不同時失敗; 一致性(Consistency):操作完成后,所有數據必須符合業務規則,否則事務必須中止; 隔離性(...