spring之事務管理

事務簡介:

事務管理是企業級應用程序開發中必不可少的技術,用來確保數據的完整性和一致性

事務就是一系列的動作,它們被當作一個單獨的工作單元。這些動作要麼全部完成,要麼全部不起作用

事務的四個關鍵屬性(ACID)

① 原子性(atomicity):事務室一個原子操作,有一系列動作組成。事務的原子性確保動作要麼全部完成,要麼完全不起作用
② 一致性(consistency):一旦所有事務動作完成,事務就被提交。數據和資源就處於一種滿足業務規則的一致性狀態中
③ 隔離性(isolation):可能有許多事務會同時處理相同的數據,因此每個事物都應該與其他事務隔離開來,防止數據損壞
④ 持久性(durability):一旦事務完成,無論發生什麼系統錯誤,它的結果都不應該受到影響。通常情況下,事務的結果被寫到持久化存儲器中

Spring中的事務管理

作爲企業級應用程序框架,Spring在不同的事務管理API之上定義了一個抽象層。而應用程序開發人員不必瞭解底層的事務管理API,就可以使用Spring的事務管理機制。

Spring既支持編程式事務管理,也支持聲明式的事務管理

編程式事務管理:將事務管理代碼嵌入到業務方法中來控制事務的提交和回滾,在編程式事務中,必須在每個業務操作中包含額外的事務管理代碼

聲明式事務管理:大多數情況下比編程式事務管理更好用。它將事務管理代碼從業務方法中分離出來,以聲明的方式來實現事務管理。事務管理作爲一種橫切關注點,可以通過AOP方法模塊化。Spring通過Spring AOP框架支持聲明式事務管理。

Spring事務的傳播屬性:

當事務方法被另一個事務方法調用時,必須指定事務應該如何傳播。例如:方法可能繼續在現有事務中運行,也可能開啓一個新事務,並在自己的事務中運行。

事務的傳播行爲可以由傳播屬性指定。Spring定義了7種傳播行爲:

Spring支持的事務傳播行爲
傳播行爲 含義
PROPAGATION_MANDATORY 表示該方法必須在事務中運行,如果當前事務不存在,則會拋出一個異常
PROPAGATION_NESTED 表示如果當前已經存在一個事務,那麼該方法將會在嵌套事務中運行。嵌套的事務可以獨立於當前事務進行單獨地提交或回滾。如果當前事務不存在,那麼其行爲與PROPAGATION_REQUIRED一樣。注意各廠商對這種傳播行爲的支持是有所差異的。可以參考資源管理器的文檔來確認它們是否支持嵌套事務
PROPAGATION_NEVER 表示當前方法不應該運行在事務上下文中。如果當前正有一個事務在運行,則會拋出異常
PROPAGATION_NOT_SUPPORTED 表示該方法不應該運行在事務中。如果存在當前事務,在該方法運行期間,當前事務將被掛起。如果使用JTATransactionManager的話,則需要訪問TransactionManager
PROPAGATION_REQUIRED 表示當前方法必須運行在事務中。如果當前事務存在,方法將會在該事務中運行。否則,會啓動一個新的事務
PROPAGATION_REQUIRED_NEW 表示當前方法必須運行在它自己的事務中。一個新的事務將被啓動。如果存在當前事務,在該方法執行期間,當前事務會被掛起。如果使用JTATransactionManager的話,則需要訪問TransactionManager
PROPAGATION_SUPPORTS 表示當前方法不需要事務上下文,但是如果存在當前事務的話,那麼該方法會在這個事務中運行

其中PROPAGATION_REQUIRED爲默認的傳播屬性

併發事務所導致的問題

在同一個應用程序或者不同應用程序中的多個事務在同一個數據集上併發執行時,可能會出現許多意外的問題。

併發事務所導致的問題可以分爲以下三類:

① 髒讀:髒讀發生在一個事務讀取了另一個事務改寫但尚未提交的數據時。如果改寫在稍後被回滾了,那麼第一個事務獲取的數據就是無效的。

② 不可重複讀:不可重複讀發生在一個事務執行相同的查詢兩次或兩次以上,但是每次都得到不同的數據時。這通常是因爲另一個併發事務在兩次查詢期間更新了數據

③ 幻讀:幻讀與不可重複讀類似。它發生在一個事務(T1)讀取了幾行數據,接着另一個併發事務(T2)插入了一些數據時。在隨後的查詢中,第一個事務(T1)就會發現多了一些原本不存在的記錄


併發事務所導致的問題解決方案之事務隔離

解決併發問題的途徑是什麼?答案是:採取有效的隔離機制。怎樣實現事務的隔離呢?隔離機制的實現必須使用鎖,下面是鎖的基本原理:

 

a.當一個事務訪問某個數據庫資源時,如果執行的是select語句,必須爲資源加上共享鎖,如果執行的是insert,update,delete語句,必須爲資源加上排他鎖,這些鎖鎖定正在被操作的資源。

b.當第二個事務也要反問相同的資源時,如果執行的select語句,那麼也必須爲資源加上共享鎖;如果執行的是insert,update,或delete語句,也必須爲資源加上排他鎖。但此時第二個事務並非就立即能爲資源加上鎖,當第一個事務爲資源加的是共享鎖時,第二個事務能夠爲資源加上共享鎖,但當第一個事務爲資源加的是排他鎖時,第二個事務必須等待第一個事務結束,才能爲資源加上排他鎖。

 

上面已經引出了,共享鎖,排他鎖。下面來闡述一下鎖的種類及概念。

 

1.共享鎖

共享鎖用於讀取數據操作,它允許其他事務同時讀取鎖定的資源,但不允許其他事務更新它。

2.排他鎖

排他鎖用於修改數據的場合,他鎖定的資源,其他事務部能讀取也不能修改。

3.更新鎖

更新鎖在更新操作初始化截斷用來鎖定可能要被修改的資源,從而避免使用共享鎖造成的死鎖現象。

 

鎖機制能有效地解決併發事務時的各種問題,但是也會影響到併發的性能。數據庫系統提供了4種可選的事務隔離級別,它們是

a.Read Uncommited:讀未提交的數據

b.Read commited:讀已提交的數據

c.Repeateble Read:可重複讀

d.Serialable:串行化

 

Read Uncommited: 該隔離級別讀取數據時不使用任何鎖。可能會出現髒讀,不可重複讀,和虛讀的問題。

 

Read commited:返回的是讀取時間點之前已提交的數據,因此可以避免髒讀。但重複讀數據時,返回的數據和讀取時間點有關,因此會重現不可重複讀,另外還會出現虛讀現象。

 

Repeatable Read:該隔離級別能夠保證重複讀,可以避免髒讀和不可重複讀問題。

 

 

 

 

Serializable:該隔離級別能夠避免髒讀,不可重複讀和虛讀現象,是最嚴格的隔離級別。

 

上面四種隔離級別,從a-d隔離級別越來越嚴格,數據安全和真實性越來越高,但併發性能越來越低。所以選擇什麼樣的隔離級別應根據應用的具體要求而定。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章