2011-12-14 9 views
1

私はHSQLDBでHibernateを使い始めました。チュートリアルでは、彼らは反パターンの「セッションごとのセッション」を使用しないように指示しています。しかし、トランザクションをコミットするたびにセッションも閉じられます。 commit()がセッションを終了した場合、どのようにしてgetCurrentSession()を使用しないでください。Java Hibernateセッションとその有効範囲は?

私は、人々が通常どのようにセッションの範囲をどのように扱っているのか少し不思議です。私はリクエストごとに1つのセッションがあるWebアプリケーションを構築する上でいくつかのサンプルを見てきました。私の場合、私はサービスを構築しており、同じ考えを適用することはできません。このサービスは24時間365日稼働しており、散発的にデータベース操作を行っています。私はデータベースセッションを常に稼働状態にし、トランザクションをトランザクション間の境界として使用するか(トランザクションコミットがセッションを閉じない場合を考慮)、各操作ごとに新しいトランザクションを作成するだけでよいでしょうか(これは、パターンが、他の方法は?)。

ありがとうございます!

+0

デーモンの意味で「サービス」を意味するのか、Web以外の何らかの方法でちょうどやり取りしている外部の消費者に公開される「サービス」を意味しますか? – Affe

+0

私はデーモンの意味で「サービス」を意味します、申し訳ありませんが、それを明確にしておくべきです。 – joscarsson

答えて

3

この動作は、使用中のCurrentSessionContextの実装によって決まります。デフォルトはThreadLocalSessionContextであり、クローズ・オン・コミットしますが、決してそれに制約されません。

ManagedSessionContextを使用して、任意のタイプのセッションスコープを構成/構築することができ、適切なライフサイクルの開始時と終了時にセッションをバインド/バインド解除できます。あなたのサービスの作業ユニットへのエントリでセッションをバインドし、終了時にバインドを解除することはあなたにとって意味があるようです。 (例外はその方法の一つから出てくる場合は特に、あなたが新しいSessionを作るために期待していることを覚えておいてください。もちろん、これを行うための堅牢なコードをビルドするための簡単な作業ではありません。)


コメントへの対応しますコメントにはあまりにも大きくなっていた。

これは、ユーザーが提供する追加の作業や設定なしに「安全」なのは、これが唯一のものだからです。 Hibernateが助けてくれないとHibernateが "見る"ことができる唯一のライフサイクルポイントは "コミット"だけなので、そこに閉じたり、セッションが永遠にぶら下がってしまうリスクがあります。

潜在的なセッションライフサイクルの境界を特定するには、実際に行っていることについてかなりの知識が必要です。 "それはバックグラウンドサービスです"とは言いません。アイドル状態で座ったり、X分ごとに目を覚ましたり、いくつかの作業をしたり、別のX分寝る前に戻ったりすると、セッションを終了してセッションを終了するのがよい境界になると仮定すると、

「セッションごとの操作」がアンチパターンであると話す場合、「操作」の広範な定義を使用している可能性があります。

彼ら(あなたのサービスのための架空の要件)のような何かをしません意味:

  1. モーニングコールサービス
  2. オープンセッション
  3. データベースから
  4. 読むファイルの場所
  5. 閉じるセッション
  6. をファイルを開く
  7. 公開セッション
  8. 更新データ現在のファイルの状態からテーブル
  9. 閉じるセッション
  10. オープンセッション
  11. ASE 1であることを行うには完全に合理的であるデータベース
  12. 閉じるセッション
  13. スリープサービス

にアクティビティログを書きますセッションを終了し、最後に閉じます。既知の境界内ですべてを自分で管理しているシングルスレッド環境では、必要に応じてcurrentSessionを使わずに自分でセッションを開いたり閉じることができます。例外が発生した場合に閉じられることを確認するだけです。オペレーティングシステムイベントをリスンしている場合、イベント処理はセッションの完璧な範囲になります。

+0

私は参照してください。それがアンチパターンの場合、デフォルトのThreadLocalSessionContextはなぜですか? サービス開始時にgetCurrentSession()を使用し、シャットダウン時に閉じる必要があります。 – joscarsson

+0

udpated答え、コメントが長すぎる – Affe

+0

徹底的な説明をありがとう!私はManagedSessionContextに変更しましたが、私の場合、これは現在のスレッドとセッションを結びつけることと(これまでのところ)ほぼ同じです。私がしなければ、私はどこでもSessionオブジェクトを渡す必要があります。私はおそらく、後でもっと良いデザインを思いつくでしょう...あなたの意見を多くありがとう! – joscarsson

関連する問題