javascript
Spring实战(十三)Spring事务
1、什么是事務(Transaction)?
? ? ? ?事務是指邏輯上的一組操作,要么全部成功,要么全部失敗。
事務是指將一系列數據操作捆綁成為一個整體進行統一管理。如果某一事務執行成功,則該事務中進行的所有數據更改均會提交,成為數據庫中的永久組成部分。如果事務執行時遇到錯誤必須取消或者回滾,則數據將全部恢復到操作前的狀態,所有的數據的更改均被消除。
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/
?
轉載于:https://www.cnblogs.com/bigbigbigo/p/8383272.html
總結
以上是生活随笔為你收集整理的Spring实战(十三)Spring事务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: const常量用法
- 下一篇: JavaScript 通过身份证号获取出