在平常的項目裡面,最常看到的就是使用注解 @Transactional 去操作事務。
如果稍微對spring事務有過了解的,會知道關于事務傳播機制,存在7種,
也就是:

同樣可以在注解@Transactional裡面看到, 預設配置了的是 Propagation.REQUIRED (文章的主角)
為什麼該篇文章,7種,我隻介紹一種呢?而且是介紹的是 PROPAGATION_REQUIRED 呢?
因為從上文大家已經知道,預設啥都不指定的時候,我們使用的就是PROPAGATION_REQUIRED這種方式。
往往很多小夥伴在使用聲明式事物的時候,就頂多加上一個異常指定,都是使用的預設傳播機制變量,是以如果連這個方式都不了解的話,那也太不應該了。
我們日常操作裡,對于單個方法使用事物,經常是這樣:
@Transactional(rollbackFor = Exception.class)
public Boolean add(UserInfo userInfo) {
//... 業務處理
//... 業務處理
//... 業務處理
//手動抛異常 觸發復原等
retrun xxx;
}
或者說配合手動復原使用,是這樣:
@Transactional(rollbackFor = Exception.class)
public Boolean add(UserInfo userInfo) {
try {
//....業務邏輯處理
if(XXXX){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
//....業務邏輯處理
if(xxxxx){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
} catch (Exception e) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
}
以上都是單個事物方法,了解起來很簡單,相信大多數場景大家就這麼用一下就沒有過多去理會了。
那麼接下來就是關于 這種預設的事物傳播機制 PROPAGATION_REQUIRED 我們需要關心的東西了。
在結合代碼介紹前,先把結論貼出來:
1.如果外部方法沒有開啟事務的話,Propagation.REQUIRED(預設就是)修飾的内部方法會新開啟自己的事務,且開啟的事務互相獨立,互不幹擾。
2.如果外部方法開啟事務并且指定為Propagation.REQUIRED(預設就是),所有Propagation.REQUIRED修飾的内部方法和外部方法均屬于同一事務 ,隻要一個方法復原,整個事務均復原,因為大家都加入到了外部設定的這個事務裡了。
第一種情形:
第一個業務類裡面的方法,使用了聲明式事務:
class testOne
{
@Transactional(rollbackFor = Exception.class)
public Boolean addOne(UserInfo userInfo) {
//... 業務處理
//... 業務處理
//... 業務處理
retrun xxx;
}
}
第二個業務類裡面的方法,也使用了聲明式事務:
class testTwo
{
@Transactional(rollbackFor = Exception.class)
public Boolean addTwo(UserInfo userInfo) {
//... 業務處理
//... 業務處理
//... 業務處理
retrun xxx;
}
}
然後第三個業務類裡面的方法沒有使用聲明式事務,去調用第一個和第二個,如:
class testThree
{
public Boolean testThree(UserInfo userInfo) {
addOne(xxxx);
addTwo(xxxx);
retrun xxx;
}
}
這種情況下,addOne和addTwo兩個方法的事務都是各自獨立的, 也就是說,就算addOne成功了,在執行addTwo的時候出現了異常進行了復原,并不會影響到addOne的資料。
那麼,在預設addOne和addTwo都使用了事務,而且都是預設指定的傳播機制PROPAGATION_REQUIRED的時候,我們想達到,隻要這兩個方法,或者testThree 方法,其中一個出現異常觸發復原,都可以将這三個方法一起進行復原。那應該怎麼做?
第二種情形:
讓它們都加入到一個事務裡面:
class testThree
{
@Transactional(rollbackFor = Exception.class)
public Boolean testThree(UserInfo userInfo) {
addOne(xxxx);
addTwo(xxxx);
retrun xxx;
}
}
在testThree方法(對于addOne 和 addTwo 來說是個外部方法)上同樣使用聲明式事物,且也是預設指定傳播機制PROPAGATION_REQUIRED。
這樣addOne事物開啟時,發現外部存在指定傳播機制PROPAGATION_REQUIRED的事物,那麼就會加入該事物;
同樣addTwo同理。
ok,簡單的介紹就到此(在看完這篇,是否對事務傳播的設定有了興趣? 有的話就開始手動去做點測試,都去試試各自傳播機制的情形,這樣才能更靈活的去運用起來)。