事務處理
Spring Boot事務機制實質上就是Spring的事務處理機制,
1 事務的4大特性
原子性(Atomicity)
一個事務要么全部提交成功,要么全部失敗回滾,不能只執行其中的一部分操作,
一致性(Consistency)
一旦事務完成(不管成功還是失敗),系統必須確保涉及的資料處于一致的狀態,而不會是部分完成部分失敗,資料不應該被破壞,
隔離性(Isolation)
并發環境下,一個事務的執行不能不被其他事務干擾,不同的事務并發操作相同的資料時,每個事務都有各自完成的資料空間,
即一個事務內部的操作及使用的資料對其他并發事務時隔離的,并發執行的各個事務之間不能相互干擾,
持久性(Durability)
一旦事務提交,那么它對資料庫中的對應資料的狀態的變更就會永久保存到資料庫中,
2 事務的傳播機制
事務的傳播性一般用在事務嵌套的場景,比如一個事務方法里面呼叫了另外一個事務方法,
那么兩個方法是各自作為獨立的方法提交還是內層的事務合并到外層的事務一起提交,這就是需要事務傳播機制的配置來確定怎么樣執行,
即:一個新的事務應該被啟動還是被掛起,或者是一個方法是否應該在事務性背景關系中運行,
事務傳播機制有以下幾種:
PROPAGATION_REQUIRED
Spring默認的傳播機制,能滿足絕大部分業務需求,如果外層有事務,則當前事務加入到外層事務,一塊提交,一塊回滾,
如果外層沒有事務,新建一個事務執行,
PROPAGATION_REQUES_NEW
每次都會新開啟一個事務,同時把外層事務掛起,當當前事務執行完畢,恢復上層事務的執行,如果外層沒有事務,執行當前新開啟的事務即可,
PROPAGATION_SUPPORT
如果外層有事務,則加入外層事務,如果外層沒有事務,則直接使用非事務方式執行,完全依賴外層的事務,
PROPAGATION_NOT_SUPPORT
不支持事務,如果外層存在事務則掛起,執行完當前代碼,則恢復外層事務,無論是否例外都不會回滾當前的代碼,
PROPAGATION_NEVER
不支持外層事務,即如果外層有事務就拋出例外,
PROPAGATION_MANDATORY
與NEVER相反,如果外層沒有事務,則拋出例外,
PROPAGATION_NESTED
保存狀態保存點,當前事務回滾到某一個點,從而避免所有的嵌套事務都回滾,即各自回滾各自的,
如果子事務沒有把例外吃掉,基本還是會引起全部回滾的,
3 事務的隔離級別
3.1 事務并發
并發環境下,多個事務同時運行,會導致以下的問題:
臟讀
一個事務讀取了被另一個事務改寫但尚未提交的資料,
如果這些改變在稍后被回滾了,那么第一個事務讀取的資料就會是無效的,
不可重復讀
一個事務執行相同的查詢兩次或兩次以上,但每次查詢結果都不相同,
通常是由于另一個并發事務在兩次查詢之間更新了資料,
不可重復讀的重點是修改,同樣的條件, 你讀取過的資料, 再次讀取出來發現值不一樣了,
幻讀
當一個事務(T1)讀取幾行記錄后,另一個并發事務(T2)插入了一些記錄時,在后來的查詢中,第一個事務(T1)就會發現一些原來沒有的額外記錄,
幻讀的重點在于新增或者洗掉,同樣的條件, 第1次和第2次讀出來的記錄數不一樣,
3.2 隔離級別
在理想狀態下,事務之間應滿足隔離性,防止上述問題發生,
在標準SQL規范中,定義了以下4個事務隔離級別,不同的隔離級別對事務的處理不同,
ISOLATION_DEFAULT
使用后端資料庫默認的隔離級別,
ISOLATION_READ_UNCOMMITTED
讀未提交,未授權讀取,允許臟讀取,其隔離級別最低,
比如事務A和事務B同時進行,事務A在整個執行階段,會將某資料的值從1開始一直加到10,然后進行事務提交,
此時,事務B能夠看到這個資料項在事務A操作程序中的所有中間值(如1變成2,2變成3等),而對這一系列的中間值的讀取就是未授權讀取,
ISOLATION_READ_COMMITTED
已提交讀,授權讀取,Oracle默認級別,只允許獲取已經提交的資料,
比如事務A和事務B同時進行,事務A進行+1操作,此時,事務B無法看到這個資料項在事務A操作程序中的所有中間值,只能看到最終的10,
另外,如果說有一個事務C,和事務A進行非常類似的操作,只是事務C是將資料項從10加到20,此時事務B也同樣可以讀取到20,
即授權讀取允許不可重復讀取,
ISOLATION_REPEATABLE_READ
可重復讀,MYSQL默認級別,禁止不可重復讀取和臟讀取,但是有可能出現幻讀,
ISOLATION_SERIALIZABLE
串行化,
最嚴格的事務隔離級別,它要求所有事務被串行執行,即事務只能一個接一個的進行處理,不能并發執行,
4 事務的實作方式
SpringBoot中推薦使用@Transactional注解管理事務,簡單,
4.1 編程式事務管理
在代碼中呼叫beginTransaction()、commit()、rollback()等事務管理相關的方法進行事務的管理,
4.2 基于TransactionProxyFactoryBean的宣告式事務管理
通過配置DataSourceTransactionManager及TransactionProxyFactoryBean進行事務控制,
4.3 基于@Transactional的宣告式事務管理
標注在方法上,
@Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED,rollbackFor=Exception.class)
public void test() {
//TODO
}
配置說明
- isolation:指定事務的隔離級別,默認為
Isolation.DEFAULT - propagation:指定事務的傳播性,默認為
Propagation.REQUIRED - rollbackFor:指定回滾的例外類,可多個
- noRollbackFor:指定不回滾的例外類,可多個
- readOnly:指定事務為只讀,默認false
- timeout:指定事務的超時時間,默認不限
注:
Spring中需要顯式配置DataSourceTransactionManager及
<tx:annotation-driven transaction-manager="myTracnsactionManager"/>SpringBoot中已經有自動配置了,直接使用即可
4.4 基于Aspect AOP配置事務
通過自定義AOP切點方式配置事務,
5 原始碼結構
參考文章
6 參考
【SpringBoot系列】八、SpringBoot 中的事務處理
有關Spring事務,看這一篇就足夠了
ACID
Spring事務管理之幾種方式實作事務
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/124097.html
標籤:Java
上一篇:資料結構--二叉樹(Java)
