簡體   English   中英

在事務控制器動作內部執行事務服務調用

[英]grails transactional service calls inside transactional controller action

這兩個控制器動作之間有什么區別:

  @Transactional
    def save(SomeDomain someDomain) {
        someDomain.someProperty = firstService.createAndSaveSomething(params)    //transactional
        someDomain.anotherProperty = secondService.createAndSaveSomething(params) //transactional
        someDomain.save(flush: true)
    }

    def save(SomeDomain someDomain) {
        combinedService.createAndSave(someDomain, params) //transactional, encapsulating first and second service calls
    }

我的目的是在事務失敗時回退整個save()操作。 但不確定我應該使用哪一個。

您可以使用兩種方法。

firstServicesecondService引發異常時,清單1將回滾控制器事務。

在上市#2(我希望createAndSave的方法combinedService與被注解@Transactional )如果將回滾事務createAndSave拋出異常。 使用此方法的最大好處是,該服務方法在理論上可在其他控制器中重用。

@Transactional的關鍵點之一是要考慮兩個單獨的概念,每個概念都有自己的范圍和生命周期:

  1. 持久性環境
  2. 數據庫事務

事務注釋本身定義了單個數據庫事務的范圍。 數據庫事務在持久性上下文的范圍內發生。 您的代碼:

@Transactional
    def save(SomeDomain someDomain) {
        someDomain.someProperty = firstService.createAndSaveSomething(params)    //transactional
        someDomain.anotherProperty = secondService.createAndSaveSomething(params) //transactional
        someDomain.save(flush: true)
    }

持久性上下文在JPA中是EntityManager,使用Hibernate Session在內部實現(當使用Hibernate作為持久性提供程序時)。 您的代碼:

def save(SomeDomain someDomain) {
        combinedService.createAndSave(someDomain, params) //transactional, encapsulating first and second service calls
    }

注意:持久性上下文只是一個同步器對象,該對象跟蹤一組有限的Java對象的狀態,並確保最終將這些對象上的更改持久化回到數據庫中。

結論:聲明式事務管理機制( @Transactional )非常強大,但很容易被濫用或錯誤配置。

在機制無法正常工作或無法正常工作的情況下進行故障排除時,了解其內部工作方式將很有幫助。

暫無
暫無

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

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