事務管理與傳播機制詳解

事務的知識總結一下,參考的文章如下:

https://www.open-open.com/lib/view/open1350865116821.html

http://www.blogjava.net/robbie/archive/2009/04/05/264003.html

https://www.jb51.net/article/57589.htm

初步理解

理解事務之前,先講一個你日常生活中最常干的事:取錢。

比如你去ATM機取1000塊錢,大體有兩個步驟:首先輸入密碼金額,銀行卡扣掉1000元錢;然后ATM出1000元錢。這兩個步驟必須是要么都執(zhí)行要么都不執(zhí)行。如果銀行卡扣除了1000塊但是ATM出錢失敗的話,你將會損失1000元;如果銀行卡扣錢失敗但是ATM卻出了1000塊,那么銀行將損失1000元。所以,如果一個步驟成功另一個步驟失敗對雙方都不是好事,如果不管哪一個步驟失敗了以后,整個取錢過程都能回滾,也就是完全取消所有操作的話,這對雙方都是極好的。

事務就是用來解決類似問題的。事務是一系列的動作,它們綜合在一起才是一個完整的工作單元,這些動作必須全部完成,如果有一個失敗的話,那么事務就會回滾到最開始的狀態(tài),仿佛什么都沒發(fā)生過一樣。

在企業(yè)級應用程序開發(fā)中,事務管理必不可少的技術,用來確保數據的完整性和一致性。

事務有四個特性:ACID

原子性(Atomicity):事務是一個原子操作,由一系列動作組成。事務的原子性確保動作要么全部完成,要么完全不起作用。

一致性(Consistency):一旦事務完成(不管成功還是失?。?,系統(tǒng)必須確保它所建模的業(yè)務處于一致的狀態(tài),而不會是部分完成部分失敗。在現實中的數據不應該被破壞。

隔離性(Isolation):可能有許多事務會同時處理相同的數據,因此每個事務都應該與其他事務隔離開來,防止數據損壞。

持久性(Durability):一旦事務完成,無論發(fā)生什么系統(tǒng)錯誤,它的結果都不應該受到影響,這樣就能從任何系統(tǒng)崩潰中恢復過來。通常情況下,事務的結果被寫到持久化存儲器中。

2 核心接口

Spring事務管理的實現有許多細節(jié),如果對整個接口框架有個大體了解會非常有利于我們理解事務,下面通過講解Spring的事務接口來了解Spring實現事務的具體策略。

Spring事務管理涉及的接口的聯系如下:


2.1 事務管理器

Spring并不直接管理事務,而是提供了多種事務管理器,他們將事務管理的職責委托給hibernate或者JTA等持久化機制所提供的相關平臺框架的事務來實現。

Spring事務管理器的接口是org.springframework.transaction.PlatformTransactionManager,通過這個接口,Spring為各個平臺如JDBC、Hibernate等都提供了對應的事務管理器,但是具體的實現就是各個平臺自己的事情了。此接口的內容如下:

Public interfacePlatformTransactionManager()...{

// 由TransactionDefinition得到TransactionStatus對象

TransactionStatusgetTransaction(TransactionDefinition definition)throwsTransactionException;

// 提交

Voidcommit(TransactionStatus status)throwsTransactionException;

// 回滾

Voidrollback(TransactionStatus status)throwsTransactionException;

? ? }

從這里可知具體的具體的事務管理機制對Spring來說是透明的,它并不關心那些,那些是對應各個平臺需要關心的,所以Spring事務管理的一個優(yōu)點就是為不同的事務API提供一致的編程模型,如JTA、JDBC、Hibernate、JPA。下面分別介紹各個平臺框架實現事務管理的機制。

2.2 基本事務屬性的定義

上面講到的事務管理器接口PlatformTransactionManager通過getTransaction(TransactionDefinition definition)方法來得到事務,這個方法里面的參數是TransactionDefinition類,這個類就定義了一些基本的事務屬性。

那么什么是事務屬性呢?事務屬性可以理解成事務的一些基本配置,描述了事務策略如何應用到方法上。事務屬性包含了5個方面,如圖所示:


2.2.1 傳播行為

事務的第一個方面是傳播行為(propagation behavior)。當事務方法被另一個事務方法調用時,必須指定事務應該如何傳播。例如:方法可能繼續(xù)在現有事務中運行,也可能開啟一個新事務,并在自己的事務中運行。Spring定義了七種傳播行為:


注:以下具體講解傳播行為的內容參考自Spring事務機制詳解?



1:PROPAGATION_REQUIRED :當前方法必須運行在事務中。如果當前事務存在,方法將會在該事務中運行。否則,會啟動一個新的事務

描述:單獨調用方法B時,只是對B方法內進行事務控制,例如:

當通過調用方法A(配置事務控制)時,A中配置有PROPAGATION_REQUIRED類別,方法A中調用方法B,B中同樣配置PROPAGATION_REQUIRED事務,根據PROPAGATION_REQUIRED的屬性,方法B對數據庫的操作會加入到方法A中,方法B捕獲異常,A會進行回滾。



2.PROPAGATION_SUPPORTS:如果存在一個事務,支持當前事務。如果沒有事務,則非事務的執(zhí)行。

描述:單純的調用methodB時,methodB方法是非事務的執(zhí)行的,當通過方法A調用時,如果方法A配置事務控制,methodB則加入了methodA的事務中,事務地執(zhí)行,方法B捕獲異常,A會進行回滾。



3.PROPAGATION_REQUIRES_NEW 總是開啟一個新的事務。如果一個事務已經存在,則將這個存在的事務掛起

描述:單獨調用B時,會自動創(chuàng)建一個事務進行操作,通過方法A調用B是,A配置PROPAGATION_REQUIRED事務。方法B配置PROPAGATION_REQUIRES_NEW?事務,當執(zhí)行B時,會把方法A的事務先掛起,當B進行完后,再提交A的事務。



4.PROPAGATION_NOT_SUPPORTED 總是非事務地執(zhí)行,并掛起任何存在的事務。

//事務屬性 PROPAGATION_REQUIRED

methodA(){

? ? methodB();

}

//事務屬性PROPAGATION_NOT_SUPPORTED

methodB(){

}


描述:單獨調用B時,非事務進行操作,通過方法A調用B是,A配置PROPAGATION_REQUIRED事務。方法B配置PROPAGATION_NOT_SUPPORTED?事務,當執(zhí)行B時,會把方法A的事務先掛起,當B進行完后,再提交A的事務。


5.PROPAGATION_NEVER 總是非事務地執(zhí)行,如果存在一個活動事務,則拋出異常。

6.PROPAGATION_NESTED? 如果一個活動的事務存在,則運行在一個嵌套的事務中. 如果沒有活動事務, 則按TransactionDefinition.PROPAGATION_REQUIRED 屬性執(zhí)行。

描述:如果單獨調用methodB方法,則按REQUIRED屬性執(zhí)行,如果調用A,相當于下面的效果:


當methodB方法調用之前,調用setSavepoint方法,保存當前的狀態(tài)到savepoint。如果methodB方法調用失敗,則恢復到之前保存的狀態(tài)。但是需要注意的是,這時的事務并沒有進行提交,如果后續(xù)的代碼(doSomeThingB()方法)調用失敗,則回滾包括methodB方法的所有操作。

嵌套事務一個非常重要的概念就是內層事務依賴于外層事務。外層事務失敗時,會回滾內層事務所做的動作。而內層事務操作失敗并不會引起外層事務的回滾。

PROPAGATION_NESTED 與PROPAGATION_REQUIRES_NEW的區(qū)別:它們非常類似,都像一個嵌套事務,如果不存在一個活動的事務,都會開啟一個新的事務。使用 PROPAGATION_REQUIRES_NEW時,內層事務與外層事務就像兩個獨立的事務一樣,一旦內層事務進行了提交后,外層事務不能對其進行回滾。兩個事務互不影響。兩個事務不是一個真正的嵌套事務。同時它需要JTA事務管理器的支持。

使用PROPAGATION_NESTED時,外層事務的回滾可以引起內層事務的回滾。而內層事務的異常并不會導致外層事務的回滾,它是一個真正的嵌套事務。DataSourceTransactionManager使用savepoint支持PROPAGATION_NESTED時,需要JDBC 3.0以上驅動及1.4以上的JDK版本支持。其它的JTA TrasactionManager實現可能有不同的支持方式。

PROPAGATION_REQUIRES_NEW 啟動一個新的, 不依賴于環(huán)境的 “內部” 事務. 這個事務將被完全 commited 或 rolled back 而不依賴于外部事務, 它擁有自己的隔離范圍, 自己的鎖, 等等. 當內部事務開始執(zhí)行時, 外部事務將被掛起, 內務事務結束時, 外部事務將繼續(xù)執(zhí)行。

另一方面, PROPAGATION_NESTED 開始一個 “嵌套的” 事務, 它是已經存在事務的一個真正的子事務. 潛套事務開始執(zhí)行時, 它將取得一個 savepoint. 如果這個嵌套事務失敗, 我們將回滾到此 savepoint. 潛套事務是外部事務的一部分, 只有外部事務結束后它才會被提交。

由此可見, PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NESTED 的最大區(qū)別在于, PROPAGATION_REQUIRES_NEW 完全是一個新的事務, 而 PROPAGATION_NESTED 則是外部事務的子事務, 如果外部事務 commit, 嵌套事務也會被 commit, 這個規(guī)則同樣適用于 roll back.

PROPAGATION_REQUIRED應該是我們首先的事務傳播行為。它能夠滿足我們大多數的事務需求。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • Spring事務機制主要包括聲明式事務和編程式事務,此處側重講解聲明式事務,編程式事務在實際開發(fā)中得不到廣泛使用,...
    EnigmaXXX閱讀 710評論 0 0
  • 一、事務的基本原理 Spring事務的本質其實就是數據庫對事務的支持,沒有數據庫的事務支持,spring是無法提供...
    芭蕾武閱讀 1,736評論 3 12
  • 事務的嵌套概念 所謂事務的嵌套就是兩個事務方法之間相互調用。spring事務開啟 ,或者是基于接口的或者是基于類的...
    jackcooper閱讀 1,501評論 0 10
  • 事務的嵌套概念 所謂事務的嵌套就是兩個事務方法之間相互調用。spring事務開啟 ,或者是基于接口的或者是基于類的...
    pigstomachs閱讀 1,100評論 0 1
  • 近年來,中國發(fā)展得越來越好,中國的文化也傳播得越來越廣。以至于很多外國人來中國學習和工作。甚至很多國家還有孔子學院...
    軒娜呀閱讀 1,211評論 0 4

友情鏈接更多精彩內容