2013-10-30 2 views
10

私は基になるセッションを取得し、もう1つは現在のトランザクションステータスへの参照を知っています。しかし、それらの違いは何か、それぞれのユースケースの例は何でしょうか?grailsのwithTransactionとwithSessionの違いは何ですか?

私の要件は、サービスメソッドブロック内の一部のレコードをバッチ保存することです。

答えて

20

withTransactionはトランザクション処理をどこからでも行うことができるので少しヒットしますが、懸念事項を分けてトランザクションサービスで作業するのが最善です。 static transactional = falseを追加しないと、サービスは@Transactional注釈でクラスおよび/またはメソッドレベルで微調整できない限り、デフォルトでトランザクションになります。 withTransactionまたはwithSessionを使わずにコードをサービスメソッドに入れても問題ありません。

withSessionは現在のHibernate Session(通常はOpenSessionInViewインターセプタによって登録されたもの)にアクセスするのに便利な方法です。セッションをクリアしたい場合や、GORMに公開されていない他の作業を行う場合は、sessionFactoryやSpringが使用するスレッドローカルの所有者にアクセスせずにアクセスしてください。トランザクションサービスメソッドのwithTransaction外の

ワンやや有効な使用では、コントローラ要求(すなわち、何の自動作成Sessionはありませんとき)の外にいるときにHibernate Sessionをバインドすることです。 withTransactionはトランザクションを開始し、必要に応じてSessionを作成し、終了時には開いたままにします。したがって、これを使用して遅延ロード例外を回避できます。トランザクションのオーバーヘッドがなくても、データベースから読み込みを行い、トランザクション書き込みを必要としない場合には、別の方法が必要です。しかし、今のところ、このアプローチが有効です。ただし、データベース書き込みを行う場合は、コードをサービスメソッドに移動します。

+0

ありがとうBurt。レコードをバッチ処理していて、 'sessionFactory.getCurrentSession().clear()'を呼び出すのが面倒だったので、 'withSession'ショートカットが必要であることがわかりました。 –

+0

この回答は厳密には当てはまりません。呼び出し元に例外をスローせずにサービスをロールバックしたい場合があります。この場合、唯一のオプションはwithTransactionを使用することです。 –

+4

本当に例外的な状態になっていない限り、例外を含むトランザクションをロールバックすることはほとんどありません。トランザクションをロールバックするためのチェックされていない例外を使用する典型的な反パターンは、副作用を利用し、例外のコストのために非効率的であり、Groovyを使用するときにはそうです。しかし、 'withTransaction'はこれを行うための唯一の正しい方法ではありません。 'TransactionAspectSupport.currentTransactionStatus()を使用してください。setRollbackOnly() ' –

3

SessionおよびTransactionStatusは、全く異なる2つのものです。 Sessionは、現在のトランザクションを制御するためにTransactionStatusを使用できる間に、すべての休止状態の機能にアクセスできる抽象です。

withSessionは、休止状態機能に直接アクセスする必要がある場合に使用できます。これは、Grails/GORMで直接サポートされていない休止状態の機能を使用する場合に便利です。

関連する問題