@Transactional注解的rollbackFor屬性

先回憶下java的異常模型,Throwable是最頂層的父類,有Error和Exception兩個子類。
Error表示嚴(yán)重的錯誤(如OOM等);
Exception可以分為運行時異常(RuntimeException及其子類)和非運行時異常(Exception的子類中,除了RuntimeException及其子類之外的類)。

非運行時異常是檢查異常(checked exceptions),一定要try catch,因為這類異常是可預(yù)料的,編譯階段就檢查的出來;
Error和運行時異常是非檢查異常(unchecked exceptions),不需要try catch,因為這類異常是不可預(yù)料的,編輯階段不會檢查,沒必要檢查,也檢查不出來

image.png

spring的@Transactional注解可以很方便的開啟事務(wù),但是默認只在遇到運行時異常和Error時才會回滾,非運行時異常不回滾,即Exception的子類中,除了RuntimeException及其子類,其他的類默認不回滾(不知道為什么要這樣設(shè)計?)
而rollbackFor屬性可以解決這個問題,rollbackFor = Exception.class表示Exception及其子類的異常都會觸發(fā)回滾,同時不影響Error的回滾。

image.png

下面是關(guān)于@Transactional注解的一些實驗

實驗一
不加rollbackFor屬性,拋出RuntimeException,正?;貪L

    @Transactional
    public void save(){
        StudentDO studentDO = new StudentDO();
        studentDO.setName("ltm");
        studentDO.setAge(22);
        studentMapper.insert(studentDO);

        throw new RuntimeException("我是異常");
    }

實驗二
不加rollbackFor屬性,拋出IOException,不回滾

    @Transactional
    public void save() throws IOException{
        StudentDO studentDO = new StudentDO();
        studentDO.setName("ltm");
        studentDO.setAge(22);
        studentMapper.insert(studentDO);

        throw new IOException();
    }

實驗三
加上rollbackFor = Exception.class,拋出IOException,正?;貪L

    @Transactional(rollbackFor = Exception.class)
    public void save() throws IOException{
        StudentDO studentDO = new StudentDO();
        studentDO.setName("ltm");
        studentDO.setAge(22);
        studentMapper.insert(studentDO);

        throw new IOException();
    }

實驗四
不加rollbackFor屬性,拋出OutOfMemoryError,正?;貪L

    @Transactional()
    public void save(){
        StudentDO studentDO = new StudentDO();
        studentDO.setName("ltm");
        studentDO.setAge(22);
        studentMapper.insert(studentDO);

        throw new OutOfMemoryError();
    }

實驗五
加上rollbackFor = Exception.class,拋出OutOfMemoryError,正?;貪L,說明rollbackFor = Exception.class不會覆蓋Error的回滾

    @Transactional(rollbackFor = Exception.class)
    public void save(){
        StudentDO studentDO = new StudentDO();
        studentDO.setName("ltm");
        studentDO.setAge(22);
        studentMapper.insert(studentDO);

        throw new OutOfMemoryError();
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容