https://blog.csdn.net/u010235716/article/details/90171802
1. 事務的4種特性
序號 參數 含義
1 原子性(Atomicity) 事務是數據庫的邏輯工作單位,它對數據庫的修改要么全部執行,要么全部不執行。
2 一致性(Consistemcy) 事務前后,數據庫的狀態都滿足所有的完整性約束。
3 隔離性(Isolation) 並發執行的事務是隔離的,一個不影響一個。通過設置數據庫的隔離級別,可以達到不同的隔離效果
4 持久性(Durability) 在事務完成以后,該事務所對數據庫所作的更改便持久的保存在數據庫之中,並不會被回滾。
2.Transactional()控制事務傳播的配置項目(默認Propagation.REQUIRED)
@Transactional(propagation=Propagation.REQUIRED) //控制事務傳播。默認是Propagation.REQUIRED
@Transactional(isolation=Isolation.DEFAULT) //控制事務隔離級別。默認跟數據庫的隔離級別相同
@Transactional(readOnly=false) //控制事務可讀寫、只可讀。默認可讀寫
@Transactional(timeout=30) //控制事務的超時時間,單位秒。默認跟數據庫的事務控制系統相同
@Transactional(rollbackFor=RuntimeException.class) //控制事務遇到哪些異常會回滾。默認是RuntimeException
@Transactional(rollbackForClassName=RuntimeException) //同上
@Transactional(noRollbackFor=NullPointerException.class) //控制事務遇到哪些異常不會回滾。默認遇到RuntimeException回滾
@Transactional(noRollbackForClassName=NullPointerException)//同上
3.事務的7中傳播特性4. 事務的傳播案例:
序號 傳播行為 含義
1 REQUIRED 如果存在一個事務,則支持當前事務。如果沒有事務則開啟一個新的事務。
2 SUPPORTS 如果存在一個事務,支持當前事務。如果沒有事務,則非事務的執行
3 MANDATORY 如果已經存在一個事務,支持當前事務。如果沒有一個活動的事務,則拋出異常。
4 NESTED 如果一個活動的事務存在,則運行在一個嵌套的事務中。如果沒有活動事務,則按REQUIRED屬性執行
5 NEVER 總是非事務地執行,如果存在一個活動事務,則拋出異常
6 REQUIRES_NEW 總是開啟一個新的事務。如果一個事務已經存在,則將這個已經存在的事務掛起
7 NOT_SUPPORTED 總是非事務地執行,並掛起任何存在的事務
4.舉個上手的按例:事務在A類的a()方法中調用B類的b()方法的傳播案例
A.a() B.b()的事務配置 a()沒有事務的結果 a()有事務的結果
REQUIRED b()創建自己的事務; b()接受a()的事務
SUPPORTS b()不創建自己的事務; b()接受a()的事務
MANDATORY b()報異常 b()接受a()的事務
NESTED b()創建自己的事務; b()接受a()的事務,成為a()嵌套的子事務
NEVER b()不創建自己的事務; b()報異常
REQUIRES_NEW b()創建自己的事務; b()不接受a()的事務,b()先執行,內層事務失敗不會影響外層事務
NOT_SUPPORTED b()不創建自己的事務; b()不接受a()的事務,b()先執行
spring 事務處理中,同一個類中:A方法(無事務)調B方法(有事務),事務不生效問題
詳見:https://blog.csdn.net/liming19890713/article/details/79225894
https://blog.csdn.net/m0_38027656/article/details/84190949
https://blog.csdn.net/levae1024/article/details/82998386
研究源碼、調試程序得出結論:
A如果沒有受事務管理: 則線程內的connection 的 autoCommit為true。
B得到事務時事務傳播特性依然生效,得到的還是A使用的connection,但是 不會改變autoCommit的屬性。
所以B當中是按照每條sql進行提交的。
解決辦法:
可以把方法B放到另外一個service或者dao,然后把這個server或者dao通過@Autowired注入到方法A的bean里面,這樣即使方法A沒用事務,方法B也可以執行自己的事務了。
Spring 事務機制回顧
Spring事務一個被訛傳很廣說法是:一個事務方法不應該調用另一個事務方法,否則將產生兩個事務. 結果造成開發人員在設計 事務方法時束手束腳,生怕一不小心就踩到地雷。
其實這是不認識Spring事務傳播機制而造成的誤解,Spring對事務控制的支持統一在TransactionDefinition類中描述,該類有以下 幾個重要的接口方法:
int getPropagationBehavior():事務的傳播行為
int getIsolationLevel():事務的隔離級別
int getTimeout():事務的過期時間
boolean isReadOnly():事務的讀寫特性
除了事務的傳播行為外,事務的其他特性Spring是借助底層資源的功能來完成的,Spring無非只充當個代理的角色。但是事務的傳播行為卻是Spring憑借自身的框架提供的功能 ;
Spring事務傳播屬性:
所謂事務傳播行為就是多個事務方法相互調用時,事務如何在這些方法間傳播。Spring支持以下7種事務傳播行為
Spring事務傳播屬性:
1.propagation-required: 支持當前事務,如果有就加入當前事務中;如果當前方法沒有事務,就新建一個事務;
2.propagation-supports: 支持當前事務,如果有就加入當前事務中;如果當前方法沒有事務,就以非事務的方式執行;
3.propagation-mandatory: 支持當前事務,如果有就加入當前事務中;如果當前沒有事務,就拋出異常;
4.propagation-requires_new: 新建事務,如果當前存在事務,就把當前事務掛起;如果當前方法沒有事務,就新建事務;
5.propagation-not-supported: 以非事務方式執行,如果當前方法存在事務就掛起當前事務;如果當前方法不存在事務,就以非事務方式執行;
6.propagation-never: 以非事務方式執行,如果當前方法存在事務就拋出異常;如果當前方法不存在事務,就以非事務方式執行;
7.propagation-nested: 如果當前方法有事務,則在嵌套事務內執行;如果當前方法沒有事務,則與required操作類似;
前六個策略類似於EJB CMT,第七個(PROPAGATION_NESTED)是Spring所提供的一個特殊變量。
它要求事務管理器或者使用JDBC 3.0 Savepoint API提供嵌套事務行為(如Spring的DataSourceTransactionManager)
在同一個類中,一個方法調用另外一個有注解(比如@Async,@Transational)的方法,注解是不會生效的
