spring事務傳播機制
spring事務傳播機制和隔離級別
1.事務傳播是什麼?
假如有A,B兩個方法,方法A有事務,方法B無事務。這時,用呼叫方法A而方法A會呼叫方
法B,無事務方法B就會對A產生影響,相反事務方法A也會對B產生影響。這種影響具體是什麼
就由兩個方法所定義的事務傳播型別所決定。
2.事務傳播型別列舉Propagation
閱讀原始碼,和英文註釋可知:
事務傳播型別有7種
REQUIRED、
SUPPORTS、
MANDATORY、
REQUIRES_NEW、
NOT_SUPPORTED、
NEVER、
NESTED。
也就是說列舉類Propagation是為了結合@Transactional註解使用而設計的,這個列舉裡面定義的事務傳播行為型別與TransactionDefinition中定義的事務傳播行為型別是對應的,所以在使用@Transactional註解時我們就要使用Propagation列舉類來指定傳播行為型別,而不直接使用TransactionDefinition介面裡定義的屬性。
//Propagation為了結合@Transactional使用而設計的
//而TransactionDefinition介面定義的事務傳播行為與Propagation列舉對應,
//使用Propagation類,而不直接使用TransactionDefinition介面
package org.springframework.transaction.annotation;
import org.springframework.transaction.TransactionDefinition;
public enum Propagation {
...
}
3.七種事務傳播行為,案例理解
首先我們為事務傳播設計一個案例,比如我要錄入一個商品,加入商品的圖片。
//業務層中
public void goods(Goods a){
insertGoods(a);
}
public void img(Img b){
insertImg(b);
}
//測試層中
public void testA(){
goods(a); //新增商品a
testB(); //呼叫testB
}
public void testB(){
img(b1); //新增圖片b1
new throw Exception; //發生異常丟擲
img(b2); //新增圖片b2
}
①REQUIRED(Spring預設傳播事務)
Support a current transaction, create a new one if none exists.
支援當前事務,如果沒有事務就建立一個新事務。
情況1
//測試層中
@Transactional(propagation = Propagation.REQUIRED)
public void testA(){
goods(a); //新增商品a
testB(); //呼叫testB
}
@Transactional(propagation = Propagation.REQUIRED)
public void testB(){
img(b1); //新增圖片b1
new throw Exception; //發生異常丟擲
img(b2); //新增圖片b2
}
沒有任何資料被錄入,假如testA中沒有事務,那麼就建立一個新的事務,由於呼叫了testB,所以沿用當前事務,丟擲異常時,回滾當前事務,沒有任何資料被錄入。
情況2
//測試層中
public void testA(){
goods(a); //新增商品a
testB(); //呼叫testB
}
@Transactional(propagation = Propagation.REQUIRED)
public void testB(){
img(b1); //新增圖片b1
new throw Exception; //發生異常丟擲
img(b2); //新增圖片b2
}
商品本身被錄入,testA無事務,所有會被忽略,不會出現回滾,而testB中的事務,會因為丟擲異常而被回滾。
②SUPPORTS
Support a current transaction, throw an exception if none exists.
支援當前事務,如果不存在則丟擲異常(無事務就以無事務的方式處理)
//測試層中
public void testA(){
goods(a); //新增商品a
testB(); //呼叫testB
}
@Transactional(propagation = Propagation.SUPPORTS)
public void testB(){
img(b1); //新增圖片b1
new throw Exception; //發生異常丟擲
img(b2); //新增圖片b2
}
商品a和圖片b1被錄入,testA中無事務所以直接插入,testB延續A的無事務狀態,遇見異常後b2不執行,所以只錄入了商品a和圖片b1.
③MANDATORY
Support a current transaction, throw an exception if none exists.
支援當前事務,如果不存在則丟擲異常
//測試層中
public void testA(){
goods(a); //新增商品a
testB(); //呼叫testB
}
@Transactional(propagation = Propagation.MANDATORY)
public void testB(){
img(b1); //新增圖片b1
new throw Exception; //發生異常丟擲
img(b2); //新增圖片b2
}
只有商品a被錄入,testA無事務所有被錄入,而testB中由於沒有事務,但是遇見了異常就會全部回滾。
④REQUIRES_NEW
Create a new transaction, and suspend the current transaction if one exists.
建立一個事務,如果不存在,就掛起該事務
//測試層中
@Transactional(propagation = Propagation.REQUIRED)
public void testA(){
goods(a); //新增商品a
testB(); //呼叫testB
new throw Exception; //發生異常丟擲
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void testB(){
img(b1); //新增圖片b1
img(b2); //新增圖片b2
}
只儲存了圖片b1和b2,在執行testB會開啟一個新事務,而testA發生的異常會回滾testA中的資料,所以商品a沒有儲存。
如果將testA和testB都設定成REQUIRED,那麼所有資料都會回滾不會儲存,因為他們都是一個事務下的,資料都會回滾。
⑤NOT_SUPPORTED
Execute non-transactionally, suspend the current transaction if one exists.
以非事務方式執行,如果當前事務存在,則掛起當前事務。
//測試層中
@Transactional(propagation = Propagation.REQUIRED)
public void testA(){
goods(a); //新增商品a
testB(); //呼叫testB
}
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void testB(){
img(b1); //新增圖片b1
new throw Exception; //發生異常丟擲
img(b2); //新增圖片b2
}
只有圖片b1錄入,testA執行,當testB執行時,將testA事務掛起,直接錄入了圖片b1,但是丟擲異常b2未執行。而testA事務出現異常,開始回滾。
⑥NEVER
Execute non-transactionally, throw an exception if a transaction exists
不使用事務,如果當前事務存在,則丟擲異常
很容易理解,就是我這個方法不使用事務,並且呼叫我的方法也不允許有事務,如果呼叫我的方法有事務則我直接丟擲異常。
//測試層中
@Transactional(propagation = Propagation.REQUIRED)
public void testA(){
goods(a); //新增商品a
testB(); //呼叫testB
}
@Transactional(propagation = Propagation.NEVER)
public void testB(){
img(b1); //新增圖片b1
img(b2); //新增圖片b2
}
沒有任何資料錄入,由於testA有事務,呼叫了沒有不允許使用事務的testB,直接丟擲異常。
⑦NESTED
Execute within a nested transaction if a current transaction exists
如果當前事物存在,則巢狀在事務中執行。否則REQUIRED的操作一樣(開啟一個事務)
情況1
//測試層中
@Transactional(propagation = Propagation.REQUIRED)
public void testA(){
goods(a); //新增商品a
testB(); //呼叫testB
new throw Exception; //丟擲異常
}
@Transactional(propagation = Propagation.NESTED)
public void testB(){
img(b1); //新增圖片b1
img(b2); //新增圖片b2
}
資料都不會錄入,因為在testMain發生異常時,父事務回滾則子事務也跟著回滾了
情況2
//測試層中
@Transactional(propagation = Propagation.REQUIRED)
public void testA(){
goods(a); //新增商品a
try{
testB(); //呼叫testB
}catch(Exception e){
}
goods(a2); //呼叫testB
}
@Transactional(propagation = Propagation.NESTED)
public void testB(){
img(b1); //新增圖片b1
new throw Exception; //丟擲異常
img(b2); //新增圖片b2
}
只有商品a和a2錄入,因為testA事務捕獲了異常,testA會正常執行,而testB巢狀中丟擲異常會只回滾testB。
相關文章
- spring的事務傳播機制Spring
- Spring Boot事務傳播機制 - DZone JavaSpring BootJava
- CRUD更要知道的Spring事務傳播機制Spring
- [轉帖]帶你讀懂Spring 事務——事務的傳播機制Spring
- spring事務的傳播Spring
- 事務傳播機制之REQUIRES_NEWUI
- Spring 事務傳播行為Spring
- spring事務之傳播性Spring
- Spring事務傳播行為Spring
- 18個示例詳解 Spring 事務傳播機制(附測試原始碼)Spring原始碼
- Spring事務的傳播屬性Spring
- Springboot mini - Solon詳解(四)- Solon的事務傳播機制Spring Boot
- Spring 七種事務傳播性介紹Spring
- Spring事務的傳播行為案例分析Spring
- 什麼是事務、事務特性、事務隔離級別、spring事務傳播特性?Spring
- java spring巢狀事務詳情和事務傳播型別JavaSpring巢狀型別
- Spring事務專題(四)Spring中事務的使用、抽象機制及模擬Spring事務實現Spring抽象
- 解析Spring Boot中的事務管理機制Spring Boot
- [轉帖]Spring事務傳播屬性之REQUIRES_NEW用法SpringUI
- Spring的事務管理(一) Spring事務管理的實現,事務的屬性(隔離級別,傳播行為,只讀)Spring
- 通過實際案例摸清楚Spring事務傳播的行為Spring
- openGauss事務機制(上)
- openGauss事務機制(下)
- spring事務的傳播屬性是什麼?它會影響什麼?Spring
- redis(10)事務和鎖機制Redis
- 關於事務補償機制
- Apache Pulsar分散式事務機制Apache分散式
- mysql 事務,鎖,隔離機制MySql
- 用張量廣播機制實現神經網路反向傳播神經網路反向傳播
- Redis系列12:Redis 的事務機制Redis
- Redis系列(九):Redis的事務機制Redis
- mysql事務處理與鎖機制MySql
- Spring 事務Spring
- spring事務Spring
- spring事務傳播的Propagation.REQUIRES_NEW以及NEVER MANDATORY驗證,及其失效的詭異問題SpringUI
- MySQL中的事務原理和鎖機制MySql
- Spring 事務管理Spring
- 分散式事務之Spring事務與JMS事務(二)分散式Spring