天天看點

Springboot 跟着我了解下 事務 @Transactional 預設方式 Propagation.REQUIRED 

在平常的項目裡面,最常看到的就是使用注解  @Transactional   去操作事務。

如果稍微對spring事務有過了解的,會知道關于事務傳播機制,存在7種,

也就是:

Springboot 跟着我了解下 事務 @Transactional 預設方式 Propagation.REQUIRED 

同樣可以在注解@Transactional裡面看到, 預設配置了的是  Propagation.REQUIRED (文章的主角)

Springboot 跟着我了解下 事務 @Transactional 預設方式 Propagation.REQUIRED 
Springboot 跟着我了解下 事務 @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,簡單的介紹就到此(在看完這篇,是否對事務傳播的設定有了興趣? 有的話就開始手動去做點測試,都去試試各自傳播機制的情形,這樣才能更靈活的去運用起來)。 

繼續閱讀