質問ごとに1つの質問をする必要があります:)
質問1の場合、はい-Spring / Hibernateの統合により、コミットの前にフラッシュが確実に発生します。したがって、への呼び出しsave()
とdelete()
はフラッシュされ、どちらにも追加する必要はありませんflush: true
。また、を呼び出さない限り、呼び出していないダーティインスタンスsave()
もフラッシュされますdiscard()
。
#2の場合:サービスはデフォルトでトランザクションであるため、transactional = true
実際には冗長です。指定するだけで、と言うことができますtransactional = false
。@Transactional
ただし、作成される自動トランザクションラッパーは、アノテーションがない場合にのみ実行されます。1つ以上のアノテーションがある場合、それらはトランザクションの境界を定義します。したがって、デフォルトでは(つまり、アノテーションなし、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 -結果-td3619420.html