簡體   English   中英

spring boot @transactional如果成功則為true

[英]spring boot @transactional true if succeeded

我正在使用帶彈簧靴的彈簧4,我需要使用@transactional。 如果我錯了,請糾正我 - @transactional使我的函數在數據庫的1個事務中運行,所以如果出現問題,該函數將進行回滾,數據庫中什么都不會改變,否則它將執行提交。

我需要同時更新4行(來自4個不同的表),如果其中一行無法更新,我需要回滾。 所以在我的服務中我有這個功能:

@Transactional
public void updateDB(entity1, entity2, entity3, entity 4) {
    save(entity1);
    save(entity2);
    save(entity3);
    save(entity4);
}

現在我希望如果事務以commit結束,我的函數將返回true,否則我希望它返回false。 這樣做有什么辦法嗎?

為了清楚起見:

在其默認配置中,Spring Framework的事務基礎結構代碼僅在運行時未經檢查的異常情況下標記用於回滾的事務。 也就是說,拋出的異常是RuntimeException的實例或子類。 (默認情況下,錯誤實例也會導致回滾)。 從事務方法拋出的已檢查異常不會導致在默認配置中回滾。

請注意,您可以使用@TransactionalrollbackFor屬性回滾Business Exception,例如:

@Transactionl(rollBackFor=MyBusinessException.class)
public boolean myTransactionalMethod(){
 // stuff here
}

對於你想要的東西,只需在方法updateDB的末尾返回true:

@Transactional
public boolean updateDB(entity1, entity2, entity3, entity 4) {
    save(entity1);
    save(entity2);
    save(entity3);
    save(entity4);
    return true;
}

如果它不返回true則意味着您的事務被回滾

PS :來自spring文檔的另一個注釋

在代理模式(默認設置)下,只攔截通過代理進入的外部方法調用。 這意味着自調用(實際上,目標對象中的方法調用目標對象的另一個方法)在運行時不會導致實際的事務,即使調用的方法用@Transactional標記。 此外,必須完全初始化代理以提供預期的行為,因此您不應該在初始化代碼(即@PostConstruct)中依賴此功能。

您可以通過多種方式實現它,一個非常簡單的方法可能最終返回true,事實上只有當您的方法以返回指令結束時,您才能獲得結果,並且事務管理器將保證交易完成並且所有保存是在同一筆交易上。

但請求! 注意如果save(entity)方法與updateDB(....)屬於同一類,即使你的類或方法用@Transaction標記,save也不會在事務中。 這是Spring的一個棘手的“功能”,與spring auto proxy相關。 這個神奇的事務被觸發並傳播,因為你的類被包裝到代理Spring的代理服務器為你管理事務。 對於bean創建生命周期中的Spring bean來說,這是必需的。 但是,如果在您的@Transactional類A中調用A類的其他方法,則您的服務調用不會從代理傳遞,而第二個服務調用不在事務中。

我舉個例子:

@Transactional
class A {


    public Entity save(Entity e) {
        .....
    }

    public Entity update(Entity e) {
        .....
        // the save method is not proxed becouse it is callled from the current instance and not
        // form the proxed spring bean instance
        save(e);
        ...
    }
}



@Transactional
class SaveA {


    public Entity save(Entity e) {
.....
    }


}

@Transactional
class UpdateA {


    private final SaveA saveA;

    UpdateA(SaveA saveA) {
        this.saveA = saveA;
    }

    public Entity update(Entity e) {
        .....
        // the save method is proxed becouse it is called from saveA that is a proxed bean
        saveA.save(e);
        ...
    }

}

很難做到這一點。 實際提交發生在@Transactional返回的方法之后。 例如,在將數據寫入表時,將完成數據庫需要執行的某些檢查。 例如,只有在將數據寫入磁盤時才會捕獲對數據庫的約束沖突。 到那時,該方法已經返回。 因此,即使從方法返回狀態,當數據庫因某些錯誤而執行回滾時,您的方法會返回成功。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM