[英]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()操作。 但不確定我應該使用哪一個。
您可以使用兩種方法。
當firstService
或secondService
引發異常時,清單1將回滾控制器事務。
在上市#2(我希望createAndSave
的方法combinedService
與被注解@Transactional
)如果將回滾事務createAndSave
拋出異常。 使用此方法的最大好處是,該服務方法在理論上可在其他控制器中重用。
@Transactional
的關鍵點之一是要考慮兩個單獨的概念,每個概念都有自己的范圍和生命周期:
事務注釋本身定義了單個數據庫事務的范圍。 數據庫事務在持久性上下文的范圍內發生。 您的代碼:
@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.