事務管理

 結合Spring的事務配置,描述jdbc的事務

 

參考文檔:

1、http://www.javaeye.com/topic/78674

2、http://www.javaeye.com/topic/35907

 

使用Spring聲明式事務時,有一個非常重要的概念就是事務屬性。事務屬性通常由事務的傳播行爲,事務的隔離級別,事務的超時值和事務只讀標誌組成。我們在進行事務劃分時,需要進行事務定義,也就是配置事務的屬性。
Spring在TransactionDefinition接口中定義這些屬性,以供PlatfromTransactionManager使用, PlatfromTransactionManager是spring事務管理的核心接口。

 

  getTimeout()方法:它返回事務必須在多少秒內完成。
isReadOnly()方法:事務是否只讀,事務管理器能夠根據這個返回值進行優化,確保事務是隻讀的。
getIsolationLevel()方法:返回事務的隔離級別,事務管理器根據它來控制另外一個事務可以看到本事務內的哪些數據。

getPropagationBehavior()方法:返回事務的傳播行爲,由是否有一個活動的事務來決定一個事務調用。

 

 

在TransactionDefinition接口中定義了五個不同的事務隔離級別。
ISOLATION_DEFAULT 這是一個PlatfromTransactionManager默認的隔離級別,使用數據庫默認的事務隔離級別.另外四個與JDBC的隔離級別相對應;
ISOLATION_READ_UNCOMMITTED 這是事務最低的隔離級別,它充許別外一個事務可以看到這個事務未提交的數據。這種隔離級別會產生髒讀,不可重複讀和幻像讀;
ISOLATION_READ_COMMITTED 保證一個事務修改的數據提交後才能被另外一個事務讀取。另外一個事務不能讀取該事務未提交的數據。這種事務隔離級別可以避免髒讀出現,但是可能會出現不可重複讀和幻像讀;
ISOLATION_REPEATABLE_READ 這種事務隔離級別可以防止髒讀,不可重複讀。但是可能出現幻像讀。它除了保證一個事務不能讀取另一個事務未提交的數據外,還保證了避免在一個事務中前後兩次讀取的結果不一致的情況產生(不可重複讀);
ISOLATION_SERIALIZABLE 這是花費最高代價但是最可靠的事務隔離級別。事務被處理爲順序執行。除了防止髒讀,不可重複讀外,還避免了幻像讀。

髒讀是讀取了未提交的數據(數據不一定被提交),不可重複讀是讀取了提交事務前後的數據(數據值不一致),幻像讀是讀取了新增數據事務前後的數據(數據行不一致)。

 

 

在TransactionDefinition接口中定義了七個事務傳播行爲。
PROPAGATION_REQUIRED  如果存在一個事務,則支持當前事務。如果沒有事務則開啓一個新的事務;
PROPAGATION_SUPPORTS  如果存在一個事務,支持當前事務。如果沒有事務,則非事務的執行。但是對於事務同步的事務管理器,PROPAGATION_SUPPORTS與不使用事務有少許不同;
PROPAGATION_MANDATORY  如果已經存在一個事務,支持當前事務。如果沒有一個活動的事務,則拋出異常;
PROPAGATION_REQUIRES_NEW  總是開啓一個新的事務。如果一個事務已經存在,則將這個存在的事務掛起;
PROPAGATION_NOT_SUPPORTED  總是非事務地執行,並掛起任何存在的事務;
PROPAGATION_NEVER  總是非事務地執行,如果存在一個活動事務,則拋出異常;
PROPAGATION_NESTED  如果一個活動的事務存在,則運行在一個嵌套的事務中. 如果沒有活動事務, 則按TransactionDefinition.PROPAGATION_REQUIRED 屬性執行;
 
嵌套事務,使用JDBC 3.0驅動時,僅僅支持DataSourceTransactionManager作爲事務管理器。需要JDBC 驅動的java.sql.Savepoint類。有一些JTA的事務管理器實現可能也提供了同樣的功能。
使用PROPAGATION_NESTED,還需要把PlatformTransactionManager的nestedTransactionAllowed屬性設爲true; 而nestedTransactionAllowed屬性值默認爲false;
嵌套事務一個非常重要的概念就是內層事務依賴於外層事務。外層事務失敗時,會回滾內層事務所做的動作。而內層事務操作失敗並不會引起外層事務的回滾。

 

PROPAGATION_NESTED 與PROPAGATION_REQUIRES_NEW的區別:
它們非常類似,都像一個嵌套事務,如果不存在一個活動的事務,都會開啓一個新的事務。使用PROPAGATION_REQUIRES_NEW時,內層事務與外層事務就像兩個獨立的事務一樣,一旦內層事務進行了提交後,外層事務不能對其進行回滾。兩個事務互不影響。兩個事務不是一個真正的嵌套事務。同時它需要JTA事務管理器的支持。
使用PROPAGATION_NESTED時,外層事務的回滾可以引起內層事務的回滾。而內層事務的異常並不會導致外層事務的回滾,它是一個真正的嵌套事務。DataSourceTransactionManager使用savepoint支持PROPAGATION_NESTED時,需要JDBC 3.0以上驅動及1.4以上的JDK版本支持。其它的JTA TrasactionManager實現可能有不同的支持方式。
JDBC3.0以上時,PROPAGATION_NESTED 開始一個 "嵌套的" 事務時,  它是已經存在事務(外部事務)的一個真正的子事務. 潛套事務開始執行時,  它將取得一個外部事務的 savepoint. 如果這個嵌套事務失敗, 我們將回滾到此 savepoint. 潛套事務是外部事務的一部分, 只有外部事務結束後它纔會被提交,外部事務回滾時將被一起回滾掉。

 

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

 

發佈了42 篇原創文章 · 獲贊 4 · 訪問量 26萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章