国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

詳解Spring中的Transactional屬性

發(fā)布時(shí)間:2021-07-05 18:40 來(lái)源:腳本之家 閱讀:0 作者:丶煒欽 欄目: 開(kāi)發(fā)技術(shù) 歡迎投稿:712375056

目錄

一、Transactional

聲明式事務(wù)管理建立在A(yíng)OP之上的。其本質(zhì)是對方法前后進(jìn)行攔截,然后在目標方法開(kāi)始之前創(chuàng )建或者加入一個(gè)事務(wù),在執行完目標方法之后根據執行情況提交或者回滾事務(wù)。

簡(jiǎn)而言之,@Transactional注解在代碼執行出錯的時(shí)候能夠進(jìn)行事務(wù)的回滾。

二、使用說(shuō)明

  • 在啟動(dòng)類(lèi)上添加@EnableTransactionManagement注解。
  • 用于類(lèi)上時(shí),該類(lèi)的所有 public 方法將都具有該類(lèi)型的事務(wù)屬性,同時(shí),我們也可以在方法級別使用該標注來(lái)覆蓋類(lèi)級別的定義。
  • 在項目中,@Transactional(rollbackFor=Exception.class),如果類(lèi)加了這個(gè)注解,那么這個(gè)類(lèi)里面的方法拋出異常,就會(huì )回滾,數據里面的數據也會(huì )回滾。
  • 在@Transactional注解中如果不配置rollbackFor屬性,那么事物只會(huì )在遇到RuntimeException的時(shí)候才會(huì )回滾,加上rollbackFor=Exception.class,可以讓事物在遇到非運行時(shí)異常時(shí)也回滾。

而至于什么是運行時(shí)異常(RuntimeException),什么是非運行時(shí)異常,可通過(guò)下圖所示理解(圖片截取網(wǎng)絡(luò ))

三、注解失效問(wèn)題

正常情況下,只要在方法上添加@Transactional注解就完事了,但是需要注意的是,雖然使用簡(jiǎn)單,但是如果不合理地使用注解,還是會(huì )存在注解失效的問(wèn)題。

@Transactional 應用在非 public 修飾的方法上

事務(wù)攔截器在目標方法執行前后進(jìn)行攔截,內部會(huì )調用方法來(lái)獲取Transactional 注解的事務(wù)配置信息,調用前會(huì )檢查目標方法的修飾符是否為 public,不是 public則不會(huì )獲取@Transactional 的屬性配置信息。

@Transactional 注解屬性 rollbackFor 設置錯誤

rollbackFor 可以指定能夠觸發(fā)事務(wù)回滾的異常類(lèi)型。Spring默認拋出了未檢查unchecked異常(繼承自 RuntimeException 的異常)或者 Error才回滾事務(wù);其他異常不會(huì )觸發(fā)回滾事務(wù)。如果在事務(wù)中拋出其他類(lèi)型的異常,但卻期望 Spring 能夠回滾事務(wù),就需要指定rollbackFor屬性。

同一個(gè)類(lèi)中方法調用,導致@Transactional失效

開(kāi)發(fā)中避免不了會(huì )對同一個(gè)類(lèi)里面的方法調用,比如有一個(gè)類(lèi)Test,它的一個(gè)方法A,A再調用本類(lèi)的方法B(不論方法B是用public還是private修飾),但方法A沒(méi)有聲明注解事務(wù),而B(niǎo)方法有。則外部調用方法A之后,方法B的事務(wù)是不會(huì )起作用的。這也是經(jīng)常犯錯誤的一個(gè)地方。
那為啥會(huì )出現這種情況?其實(shí)這還是由于使用Spring AOP代理造成的,因為只有當事務(wù)方法被當前類(lèi)以外的代碼調用時(shí),才會(huì )由Spring生成的代理對象來(lái)管理。

異常被你的 catch“吃了”導致@Transactional失效

如果你手動(dòng)的catch捕獲這個(gè)異常并進(jìn)行處理,事務(wù)管理器會(huì )認為當前事務(wù)應該正常commit,就會(huì )導致注解失效,如果非要捕獲且不失效,就必須在代碼塊內throw new Exception拋出異常。

數據庫引擎不支持事務(wù)

開(kāi)啟事務(wù)的前提就是需要數據庫的支持,我們一般使用的Mysql引擎時(shí)支持事務(wù)的,所以一般不會(huì )出現這種問(wèn)題。

開(kāi)啟多線(xiàn)程任務(wù)時(shí),事務(wù)管理會(huì )受到影響

因為線(xiàn)程不屬于spring托管,故線(xiàn)程不能夠默認使用spring的事務(wù),也不能獲取spring注入的bean在被spring聲明式事務(wù)管理的方法內開(kāi)啟多線(xiàn)程,多線(xiàn)程內的方法不被事務(wù)控制。
如下代碼,線(xiàn)程內調用insert方法,spring不會(huì )把insert方法加入事務(wù)就算在insert方法上加入@Transactional注解,也不起作用。

@Service  
public class ServiceA {  
   
    @Transactional  
    public void threadMethod(){  
        this.insert();  
         System.out.println("main insert is over");  
        for(int a=0 ;a<3;a++){  
            ThreadOperation threadOperation= new ThreadOperation();  
            Thread innerThread = new Thread(threadOperation);  
            innerThread.start();  
        }  
    }  
   
    public  class ThreadOperation implements Runnable {  
        public ThreadOperation(){  
        }  
        @Override  
        public void run(){  
            insert();  
            System.out.println("thread insert is over");  
        }  
    }  
   
    public void insert(){  
   
    //do insert......  
   
    }  
}  

如果把上面insert方法提出到新的類(lèi)中,加入事務(wù)注解,就能成功的把insert方法加入到事務(wù)管理當中

@Service  
public class ServiceA {  
   
@Autowired  
private ServiceB serviceB;  
   
    @Transactional  
    public void threadMethod(){  
        this.insert();  
        System.out.println("main insert is over");  
        for(int a=0 ;a<3;a++){  
            ThreadOperation threadOperation= new ThreadOperation();  
            Thread innerThread = new Thread(threadOperation);  
            innerThread.start();  
        }  
    }  
   
    public  class ThreadOperation implements Runnable {  
        public ThreadOperation(){  
        }  
        @Override  
        public void run(){  
            serviceB.insert();  
            System.out.println("thread insert is over");  
        }  
    }  
   
    public void insert(){  
   
        //do insert......  
   
    }  
}  
   
@Service  
public class ServiceB {  
   
    @Transactional  
    public void insert(){  
   
        //do insert......  
   
    }  
   
}  

另外,使用多線(xiàn)程事務(wù)的情況下,進(jìn)行回滾,比較麻煩。thread的run方法,有個(gè)特別之處,它不會(huì )拋出異常,但異常會(huì )導致線(xiàn)程終止運行。

最麻煩的是,在線(xiàn)程中拋出的異常即使在主線(xiàn)程中使用try…catch也無(wú)法截獲這非常糟糕,我們必須要“感知”到異常的發(fā)生。比如某個(gè)線(xiàn)程在處理重要的事務(wù),當thread異常終止,我必須要收到異常的報告,才能回滾事務(wù)。這時(shí)可以使用線(xiàn)程的UncaughtExceptionHandler進(jìn)行異常處理,UncaughtExceptionHandler名字意味著(zhù)處理未捕獲的異常。更明確的說(shuō),它處理未捕獲的運行時(shí)異常。

如下代碼
線(xiàn)程出要使用
①處要拋出異常
②處要捕捉異常,并且要拋出RuntimeException
③處手動(dòng)處理回滾邏輯

@Service  
public class ServiceA {  
   
@Autowired  
private ServiceB serviceB;  
   
    @Transactional  
    public void threadMethod(){  
        this.insert();  
        System.out.println("main insert is over");  
        for(int a=0 ;a<3;a++){  
            ThreadOperation threadOperation= new ThreadOperation();  
            Thread innerThread = new Thread(threadOperation);  
            innerThread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {  
               public void uncaughtException(Thread t, Throwable e) {  
                   try {  
                        serviceB.delete();③  
                   } catch (Exception e1) {  
                       e1.printStackTrace();  
                   }  
               }  
            });  
            innerThread.start();  
        }  
    }  
   
    public  class ThreadOperation implements Runnable {  
        public ThreadOperation(){  
        }  
        @Override  
        public void run(){  
            try {  
               serviceB.insert();  
           }catch (Exception ex){ ②  
            System.out.println(" Exception in run ");  
               throw new RuntimeException();  
           }  
            System.out.println("thread insert is over");  
        }  
    }  
   
    public void insert(){  
   
        //do insert......  
   
    }  
}  
   
@Service  
public class ServiceB {  
   
    @Transactional  
    public void insert() throws Exception{ ①  
   
    //do insert......  
   
    }  
   
    @Transactional  
    public void delete() throws Exception{   
   
        //do delete......  
   
    }  
   
}  

到此這篇關(guān)于詳解Spring中的Transactional屬性的文章就介紹到這了,更多相關(guān)Transactional屬性詳解內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。

性少妇FREESEXVIDEOS高清BBW| 中文字幕乱码人妻无码久久| 国产毛多水多高潮高清| 亚洲AV无码成人影院一区| 欧美大胆少妇BBW| 国产欧美成aⅴ人高清|