From Gossip@caterpillar

Spring Gossip: 交易的屬性介紹

 

 


Spring使用AOP來完成宣告式的交易管理,因而宣告式交易是以方法為單位,Spring的交易屬性(Transaction attribute)自然就在於描述交易應用至方法上的策略,在Spring中交易屬性可設定以下的幾個參數:
  • 傳播行為(Propagation behavior)
傳播行為定義了交易應用於方法上之邊界(Boundaries),它告知何時該開始一個新的交易,或何時交易該被暫停,或者方法是否要在交易中進行。

Spring定義幾個傳播行為,可在TransactionDefinition的API文件說明上找到相對應的常數與說明,以下列出幾個:

傳播行為

說明

PROPAGATION_MANDATORY

方法必須在一個現存的交易中進行,否則丟出例外

PROPAGATION_NESTED

在一個巢狀的交易中進行,如果不是的話,則同PROPAGATION_REQUIRED

PROPAGATION_NEVER

指出不應在交易中進行,如果有的話就丟出例外

PROPAGATION_NOT_SUPPORTED

指出不應在交易中進行,如果有的話就暫停現存的交易

PROPAGATION_REQUIRED

支援現在的交易,如果沒有的話就建立一個新的交易

PROPAGATION_REQUIRES_NEW

建立一個新的交易,如果現存一個交易的話就暫停它

PROPAGATION_SUPPORTS

支援現在的交易,如果沒有的話就以非交易的方式執行


舉個例子來說,如果傳播行為被宣告為 PROPAGATION_REQUIRED,則交易的邊界在於第一個開始交易的方法呼叫及結束時,如果先前沒有交易被開始,則交易邊界即為目前的方法呼叫 前後。又如果傳播行為被宣告為PROPAGATION_REQUIRES_NEW,則交易的邊界即為該方法呼叫的前後。

  • 隔離層級(Isolation level)
在一個應用程式中,可能有多個交易同時在進行,這些交易應當彼此之間互相不知道另一個交易的存在,好比現在整個應用程式就只有一個交易存在的樣子,由於交易彼此之間獨立,若讀取的是同一個資料的話,就容易發生問題,例如:
    • Dirty read
某個交易已更新一份資料,另一個交易在此時讀取了同一份資料,由於某些原因,前一個交易回滾(Roll back)了操作,則後一個交易所讀取的資料就會是不正確的。
    • Non-repeatable read
在一個交易的兩次查詢之中資料不一致,可能因為兩次查詢過程中間插入了一個交易更新的原有的資料。
    • Phantom read
在一個交易的兩次查詢中資料筆數不一致,例如有一個交易查詢了幾列(Row)資料,而另一個交易卻在此時插入了新的幾列數據,先前的交易在接下來的查詢中,就會發現有幾列數據是它先前所沒有的。

為了避免以上問題的方法之一,就是在某個交易進行過程中鎖 定正在更新或查詢的資料欄位,直到目前的交易完成,然而完全的鎖定欄位時,另一個交易來進行查詢同一份資料時就必須等待,直到前一個交易完成並解除鎖定為 止,因而會造成應用程式在查詢或更新資料時效能上的問題,而事實上根據需求的不同,並不用在交易進行時完全的鎖定資料,隔離層級讓您根據實際的需求,對資 料的鎖定進行設置。

Spring提供了幾種隔離層級設定,同樣的可以在TransactionDefinition的API文件說明上找到相對應的常數與說明,以下列出幾個:

隔離層級

說明

ISOLATION_DEFAULT

使用底層資料庫預設的隔離層級

ISOLATION_READ_COMMITTED

允許交易讀取其它並行的交易已經送出(Commit)的資料欄位,可以防止Dirty read問題

ISOLATION_READ_UNCOMMITTED

允許交易讀取其它並行的交易還沒送出的資料,會發生DirtyNonrepeatablePhantom read等問題

ISOLATION_REPEATABLE_READ

要求多次讀取的資料必須相同,除非交易本身更新資料,可防止DirtyNonrepeatable read問題

ISOLATION_SERIALIZABLE

完整的隔離層級,可防止DirtyNonrepeatablePhantom read等問題,會鎖定對應的資料表格,因而有效能問題

  • 唯讀提示(Read-only hints)
如果交易只進行讀取的動作,則可以利用底層資料庫在唯讀操 作時的一些最佳化動作,由於這個動作利用到資料庫在唯讀的交易操作最佳化,因而必須在交易中才有效,也就是說您要搭配傳播行為 PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、 PROPAGATION_NESTED來設置。

  • 交易超時期間(The transaction timeout period)
有的交易操作可能延續一段很長的時間,交易本身可能關聯到資料表格的鎖定,因而長時間的交易操作會有效能上的問題,對於過長的交易操作,您要考慮回滾(Roll back)交易並要求重新操作,而不是無限時的等待交易完成。

您可以設置交易超時期間,計時是從交易開始時,所以這個設置必須搭配傳播行為PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、PROPAGATION_NESTED來設置。