Spring實戰(十三)Spring事務
1、什麽是事務?
所謂事務是指邏輯上的一組操作,要麽全部成功,要麽全部失敗。
2.事務的特性
原子性:事務是一個不可分割的工作單位,事務中的操作要麽都發生,要麽都不發生。
一致性:事務前後的數據的完整性必須保持一致。
隔離性:多個用戶並發訪問數據庫,一個用戶的事務的執行不能被其他事務幹擾,多個並發事務之間的數據要相互隔離。
持續性:一個事務一旦提交,它對數據庫中數據的改變就應該是永久性的,即使數據庫發生故障也不應該有任何影響。
3.事務並發操作帶來哪些問題?
丟失修改:兩個事務T1和T2讀入同一個數據並修改,T2提交的結果破壞了T1提交的結果,導致T1的修改被丟失。
臟讀:一個事務讀取了另一個事務改寫但還未提交的數據,若這些事務被回滾,這個讀取就是無效的。
不可重復讀:在同一事務中,多次讀取同一數據返回的結果有所不同(讀時數據發生了改變)。
幻讀:一個事務讀取了幾行記錄後,另一個事務插入一些記錄,發生幻讀。後來的查詢中,第一個事務發現一些原來沒有的記錄。
4、Spring事務管理API(主要有3個)
PlatformTransactionManager:事務管理器;
TransactionDefinition:事務的定義信息(隔離,傳播,超時,只讀);
TransactionStatus:保存事務具體運作狀態
5、PlatformTransactionManager 事務管理器
spring為不同的持久化框架提供了不同的PlatformTransactionManager。
不論 采用何種方式,都必須先創建“事務管理器”的對象。
6、TransactionDefinition 定義事務(隔離,傳播,超時,只讀)
設置隔離級別:(一組常量定義)
(mysql 默認REPEATABLE_READ、oracle默認 READ_COMMITTED)
定義事務的傳播行為
應用場景:當我們調用一個基於Spring的Service接口方法(如UserService#addUser())時,它將運行於Spring管理的事務環境中,Service接口方法可能會在內部調用其它的Service接口方法以共同完成一個完整的業務操作,因此就會產生服務接口方法嵌套調用的情況, Spring通過事務傳播行為控制當前的事務如何傳播到被嵌套調用的目標服務接口方法中。
Spring在TransactionDefinition接口中規定了7種類型的事務傳播行為,它們規定了事務方法和事務方法發生嵌套調用時事務如何進行傳播:
(當使用PROPAGATION_NESTED時,底層的數據源必須基於JDBC 3.0,並且實現者需要支持保存點事務機制。)
事務傳播行為類型 |
說明 |
PROPAGATION_REQUIRED |
如果當前沒有事務,就新建一個事務,如果已經存在一個事務中,加入到這個事務中。這是最常見的選擇。 |
PROPAGATION_SUPPORTS |
支持當前事務,如果當前沒有事務,就以非事務方式執行。 |
PROPAGATION_MANDATORY |
使用當前的事務,如果當前沒有事務,就拋出異常。 |
PROPAGATION_REQUIRES_NEW |
新建事務,如果當前存在事務,把當前事務掛起。 |
PROPAGATION_NOT_SUPPORTED |
以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。 |
PROPAGATION_NEVER |
以非事務方式執行,如果當前存在事務,則拋出異常。 |
PROPAGATION_NESTED |
如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則執行與PROPAGATION_REQUIRED類似的操作。 |
此外,還有超時時間、是否只讀等相關功能。
7、TransactionStatus:保存事務狀態
接口提供了一些方法來判斷(獲得)事務當前的狀態:
void flush();沖洗數據庫底層會話
boolean hasSavePoint();返回該事務是否有一個保存點
boolean isCompleted();返回事務是否提交或者回滾
boolean isNewTransaction();返回是否是一個新事務
boolean isRollbackOnly();判斷這個事務是否已經設置了rollback-only。
void setRollbackOnly();設置這個事務rollback-only。
8、嵌套事務
嵌套是子事務套在父事務中執行,子事務是父事務的一部分。
在進入子事務之前,父事務建立一個回滾點,叫save point,然後執行子事務。這個子事務的執行也算是父事務的一部分,然後子事務執行結束,父事務繼續執行。重點就在於那個save point,看幾個問題就明白了。
如果子事務回滾,會發生什麽?
父事務會回滾到進入子事務前建立的save point,然後嘗試其他的事務或者其他的業務邏輯,父事務之前的操作不會受到影響,更不會自動回滾。
如果父事務回滾,會發生什麽?
父事務回滾,子事務也會跟著回滾!為什麽呢,因為父事務結束之前,子事務是不會提交的,我們說子事務是父事務的一部分,正是這個道理。
那麽:事務的提交,是什麽情況? 是父事務先提交,然後子事務提交,還是子事務先提交,父事務再提交?
答案是第二種情況,還是那句話,子事務是父事務的一部分,由父事務統一提交。
9、Spring支持兩種方式事務管理
——編程式的事務管理
-
- 實際開發中很少應用
- 通過TransactionTemplate手動管理事
——使用XML配置聲明事務
-
- 開發中推薦使用(代碼侵入性最小)
- Spring的聲明式事務是通過AOP實現
10、聲明式事務管理——XML配置(AOP思想)
step-01 配置事務管理器——註入dataSource,確定對哪個數據庫操作;
step-02 配置事務的增強——要做的事務操作,確定進行事務操作的方法匹配規則。(隔離級別、哪個方法進行事務)
step-03 配置切面——把通知應用到切點。
11、聲明式事務管理——註解配置
step-01 配置事務管理器——註入dataSource,確定對哪個數據庫操作;
step-02 開啟事務註解;
step-03 在要使用事務的方法所在類上面添加註解@Transactional。
參考:http://opiece.me/2016/03/18/spring-transactional-introduce/
Spring實戰(十三)Spring事務