2011-12-02 151 views
8

我正在使用Grails Web應用程序,並且在使用Grails服務時遇到了很多奇怪的事情。所以我想問一些關於這方面的問題,讓我更多地瞭解Grails服務。這對我很有幫助(也許對其他人^ _ ^)。提前致謝。有關Grails服務的一些問題

  1. 如果服務被配置爲與靜態事務=真,將它沖洗任何方法之後的每一個數據變化到DB與對象是髒並且被鎖定在休眠會話調用?

  2. 我可以在課程級別使用@Transactional註釋而不是static transactional = true嗎?是否可以將@Transactional(readOnly = true)放在我希望他們從DB讀取(查詢,查找)數據的某些方法中?

  3. 交易繼承如何?我的意思是,如果父服務配置爲static transactional = true,並且子服務擁有它自己的@Transactional註釋(在類上)以及某些@Transactional(readOnly = true)(在某些方法上),如果我從子對象調用父對象的方法會發生什麼?

  4. 是否與抽象服務進行交易?因爲據我所知,在抽象服務中,我們無法初始化其bean,也可能在啓動應用程序時,Grails上下文中存在一些差異。

回答

7

你應該問每個問題一個問題:)

對於問題#1,是 - 春/ Hibernate的整合確保了沖水發生之前提交。所以撥打save()delete()的電話將被刷新,並且不需要將flush: true添加到其中。此外,除非您致電discard(),否則您尚未調用save()的髒實例也將被刷新。

對於#2:服務在默認情況下是事務性的,因此transactional = true實際上是多餘的 - 您只需要指定它即可表示transactional = false。但是,創建的自動事務包裝僅在沒有@Transactional註釋的情況下完成。如果您有一個或多個註釋,那麼這些註釋將定義事務劃分。因此,默認情況下(即沒有註釋和transactional屬性或transactional = true)所有方法都是事務性的,但是如果您只註釋了一部分方法,那麼只有這些方法是事務性的。

通常,當您希望非默認行爲,即自定義傳播,隔離,超時等(或使其像您的示例中的只讀一樣)時,您將使用註釋。

您可以在類級註釋爲所有方法具有相同的配置,並可以選擇註釋各個方法以覆蓋類作用域默認值。

對於#3和#4,適用標準規則(請參閱#2)。如果子類有註釋,那麼來自該類或父類的transactional = true將被忽略,因爲通過使用註釋,您已告訴Grails您正在配置自己的東西。

由於抽象服務無法實例化,實際實例化的具體子類將具有基類和自身的組合行爲。如果一切都是transactional = true那麼它很簡單,如果你有任何註釋,那麼他們定義規則。

在超類中調用方法的行爲就像調用當前類中的方法一樣。但是如果您沒有考慮Spring的代理方法的含義,那麼這種行爲有點違反直覺。當您調用事務性方法時,代理攔截該調用並加入活動事務,或者根據需要啓動一個新的事務,或者如果指定了REQUIRES_NEW,則啓動一個新事務。但是,一旦你在真正的課堂上,並調用另一種方法,你會繞過代理。因此,如果您使用不同的註釋設置調用另一個方法,它們將被忽略。如果您打算這麼做,請參閱此郵件列表討論以瞭解正在進行的操作以及如何使用它:http://grails.1312388.n4.nabble.com/non-transactional-service-extends-transactional-service-outcome-td3619420.html

+0

太棒了!非常感謝你的明確答案。但讓我們看看第3點的反面:父級服務A在類級別上標記@Annotation,並且A中的方法doParent()是readOnly = true,而子級服務B沒有關於事務的任何特定配置。爲什麼我從B調用doParent(),它仍然會刷新數據,儘管我強制它只讀? –