簡體   English   中英

Grails服務交易行為

[英]Grails service transactional behaviour

在Grails應用程序中,服務方法的默認行為是它們是事務性的,如果拋出未經檢查的異常,事務將自動回滾。 但是,在Groovy中,不會強制處理(或重新拋出)已檢查的異常,因此存在一種風險,即如果服務方法拋出已檢查的異常,則不會回滾該事務。 考慮到這一點,似乎建議注釋每個Grails服務類

@Transactional(rollbackFor = Throwable.class) 
class MyService {

    void writeSomething() {
    }
}

假設我在MyService有其他方法,其中一個只讀取數據庫,另一個不接觸數據庫,以下注釋是否正確?

@Transactional(readOnly = true)
void readSomething() {}

// Maybe this should be propagation = Propagation.NOT_SUPPORTED instead?
@Transactional(propagation = Propagation.SUPPORTS)
void dontReadOrWrite() {}

為了回答這個問題,我想你需要知道我的意圖是什么:

  • 如果從任何方法拋出異常並且正在進行事務,則將回滾它。 例如,如果writeSomething()調用dontReadOrWrite() ,並且從后者拋出異常,則前者啟動的事務將被回滾。 我假設rollbackFor類級屬性是由單個方法繼承的,除非它們顯式覆蓋它。
  • 如果沒有正在進行的事務,則不會為dontReadOrWrite方法啟動dontReadOrWrite
  • 如果在調用readSomething()時沒有進行任何事務,則將啟動只讀事務。 如果正在進行讀寫事務,它將參與此事務。

你的代碼是正確的:你確實希望在服務類中的各個方法上使用Spring @Transactional注釋來獲得你正在尋找的粒度,你想要支持dontReadOrWrite(NOT_SUPPORTED將是正確的)暫停一個現有的交易,根據你所描述的內容不會給你買任何東西,並且需要你的軟件花費周期,所以沒有收獲就很痛苦,而且你想要默認的傳播行為是正確的(必需的) )for readSomething。

但是要記住Spring事務行為的一個重要事項是Spring通過將類包裝在代理中來執行事務管理,該代理執行適當的事務設置,調用您的方法,然后在控制返回時執行適當的事務拆除。 並且(至關重要), 只有在代理上調用方法時才會調用此事務管理代碼,如果writeSomething()在第一個項目符號中直接調用dontReadOrWrite(),則不會發生這種情況。

如果你需要在另一個方法調用的方法上有不同的事務行為,那么如果你想繼續使用Spring的@Transactional注釋進行事務管理,你有兩個我知道的選擇:

  1. 將另一個調用的方法移動到另一個服務類中,該服務類將通過Spring代理從原始服務類訪問。
  2. 將方法保留在原處。 聲明服務類中的成員變量與服務類的接口類型相同,並使其成為@Autowired,這將為您提供對服務類的Spring代理對象的引用。 然后,當您想要使用不同的事務行為調用您的方法時,請在該成員變量上而不是直接執行它,並且Spring事務代碼將根據您的需要觸發。

方法#1非常好,如果這兩種方法實際上並不相關,因為它可以解決您的問題,而不會混淆最終維護代碼的人,並且無法忘記調用啟用事務的方法。

方法#2通常是更好的選擇,假設您的方法由於某種原因而全部在同一服務中,並且您不希望將它們拆分出來。 但是對於一個不理解Spring事務的皺紋的維護者而言,這是令人困惑的,你必須記住在你調用它的每個地方以這種方式調用它,所以這是有代價的。 我通常願意支付這個價格,以免不自然地分裂我的服務類,但一如既往,這取決於你的情況。

我認為您正在尋找的是更細粒度的事務管理,使用@Transactional注釋是正確的方向。 也就是說,有一個Grails事務處理插件可以為您提供您正在尋找的行為。 需要注意的是,您需要將您的服務方法調用包裝在DomainClass.withTransaction閉包中,並提供您正在尋找的非標准行為作為withTransaction()方法的參數映射。

作為一個注釋,在后端,通過使用@Transactional注釋在運行時更改事務的行為,這正是您正在討論的內容。 插件文檔非常好,所以我認為如果沒有足夠的指導,你會發現自己。

希望這是你正在尋找的。

暫無
暫無

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

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