簡體   English   中英

什么是Grails的“交易”服務?

[英]What is a Grails “transactional” service?

我正在閱讀有關服務的Grails文檔,該文檔大量提及了事務/事務性,但並未真正定義事務服務方法的真正含義。

鑒於服務的性質,它們經常需要交易行為。

這到底是什么意思? 事務方法是僅使用JPA / JDBC與關系數據庫進行通信的事務方法,還是適用於JTA涵蓋的所有事務

有什么理由為什么我不會將服務類@Transactional為萬一它演變為某天使用事務? 換句話說,是否存在使所有服務方法都具有事務性的性能問題?

Grails服務默認情況下是事務性的-如果您不希望服務是事務性的,則需要刪除所有@Transactional批注(Grails的@grails.transaction.Transactional和Spring的@org.springframework.transaction.annotation.Transactional )並添加

static transactional = false

如果您沒有使用transactional屬性禁用事務並且沒有注釋,則該服務的工作方式與使用Spring注釋進行注釋的服務相同。 也就是說,在運行時,Spring將創建您的類的CGLIB代理,並將該代理的實例注冊為Spring Bean,並將其委托給實際類的實例以進行數據庫訪問和業務邏輯。 這使代理可以攔截所有公共方法調用並啟動新事務,加入現有事務,創建新事務等。

較新的Grails批注具有與Spring批注相同的所有設置,但工作方式略有不同。 編譯過程中,每個方法都由AST轉換重寫,而不是觸發單個代理的創建,本質上為每個方法創建了一個迷你代理(這顯然是一種簡化)。 這樣做更好,因為數據庫訪問和事務語義相同,但是如果您從另一個使用不同設置進行注釋的方法中調用一個被注釋的方法,則將遵循不同的設置。 但是對於代理,它是委托實例內部的直接調用,並且代理被繞過。 由於代理具有創建新事務或使用其他不同設置的所有邏輯,因此這兩種方法將使用第一種方法的設置。 使用Grails批注,每種方法都能按預期工作。

事務處理方法對性能的影響很小,如果有大量的調用和/或大量的通信量,這會累積。 在代碼運行之前,將啟動一個事務(假設其中一個未處於活動狀態),並且為此必須從池(DataSource)中檢索連接並將其配置為關閉自動提交,並進行各種事務設置(隔離,超時)。 ,只讀等)。 但是Grails數據源實際上是圍繞“真實”數據庫的智能包裝。 在啟動查詢之前,它不會獲得真正的JDBC連接,因此所有配置設置都將一直緩存到那時,然后在真正的連接上“重播”。 如果該方法不執行任何數據庫工作(或者因為它從不執行,或者因為它在數據庫訪問代碼觸發之前基於某種條件而提前退出),那么基本上沒有數據庫成本。 但是,如果確實如此,那么事情將按預期進行。

但是,不要依賴於這種DataSource代理邏輯-最好明確說明哪些服務是事務性的,哪些不是事務性的,以及在每個服務中哪些方法是事務性的,哪些不是事務性的。 最好的方法是根據需要對方法進行注釋,或者,如果所有方法都使用相同的設置,則在類級別添加單個注釋。

您可以在我所做的有關Grails中事務的討論中獲得更多信息。

首先,如果您對性能的擔心是由於您的服務具有事務性而造成的,那么您已經達到了必殺技。 我之所以這樣說,是因為在這成為主要(甚至是次要)問題之前很久,您的應用程序中就會出現許多其他瓶頸。 所以,不要為此煩惱。

通常在Grails中, transaction與數據庫連接或休眠會話的事務狀態有關。 盡管可以由JTA通過適當的Spring配置來管理。

簡單來說,(默認情況下)通常意味着數據庫事務。

暫無
暫無

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

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