13

TomcatでSpringでHibernateを使用しています。私はこのトピックに関するJBoss wiki ページを頻繁に参照し、再読してきましたが、これは役に立ちました。しかし、それは私にいくつかの疑問を残します。

  1. リクエストごとにトランザクションを開始するという考えは、私を悩ませます。フィルターを特定のコントローラーに制限できると思います-おそらく、トランザクションを必要とするすべてのコントローラーを疑似「tx」パスまたは何かの下に置きます。しかし、トランザクションが必要かどうかわからない場合にトランザクションを使用するのは悪い考えではありませんか? また、何らかのリクエストで読み取りを行っているだけの場合 (キャッシュから取得される可能性が非常に高い読み取り)、トランザクションを使用しないほうがよいのではないでしょうか?

  2. サービス層でトランザクションを処理する方法について言及している投稿を読みましたが、Spring でこれを行いたいと考えています。では、フィルタ コードはどのようなものになるでしょうか。遅延読み込みのために、ビューでセッションを利用できるようにしたいです。

  3. フィルタを呼び出すsessionFactory.getCurrentSession()だけでよい場合、再利用のためにセッション ファクトリに「解放」するにはどうすればよいでしょうか。(トランザクションを使用している場合でも、または何かが表示されると予想していましたsession.close()。) そのセッションを再利用できることをセッション ファクトリに伝えているのは誰ですか?

  4. おそらくbeginTransaction()、リクエストの期間中、特定のデータベース接続を特定のセッションにバインドする呼び出しでしょうか? それ以外の場合、セッションは必要に応じてプールからデータベース接続をプルしますよね?

私のすべての質問にご理解いただきありがとうございます。

(そして、あなたの答えが Spring のドキュメントへのリンクである場合、あなたは私を泣かせるだけです。あなたはそれを望まないでしょう? もし人々が Spring 関連の質問に答えるのをやめたら、私は本当のお金を払います。仕方。)

4

2 に答える 2

22

あなたの懸念は有効です、wikiページで提供される解決策はあまりにも単純です。トランザクションはWebレイヤーでは管理しないでください。サービスレイヤーで処理する必要があります。

正しい実装では、セッションが開かれ、フィルター内のスレッドにバインドされます。トランザクションは開始されません。セッションは決してフラッシュモードになりません-読み取り専用モード。サービス呼び出しは、セッションをフラッシュモードに自動設定し、トランザクションを開始/コミットします。サービスメソッドが終了すると、セッションフラッシュモードはneverに戻ります。

フィルタでセッションを開かないオプションもあります。各サービスレイヤー呼び出しは、個別のセッションとトランザクションを開きます。サービス呼び出しが完了した後、セッションは閉じられませんが、遅延クローズ用に登録されます。Webリクエストの処理が完了すると、セッションは閉じられます。

Springは、上記のように機能するOpensessionInViewFilterを提供します。したがって、jboss wikiの記事を無視して、OpensessionInViewFilterを設定するだけです。すべて問題ありません。

SessionFactory.getCurrentSession()-内部でセッションを作成し、ローカルスレッドに割り当てます。各リクエスト/スレッドには独自のセッションがあります。Webリクエストの処理が完了すると、セッションは閉じられます。コード内から、SessionFactory.getCurrentSession()を使用するだけで、閉じる必要はありません。jbosswikiページのコードサンプルが間違っています-finallyブロックにSessionFactory.getCurrentSession()。close()が含まれている必要があります。または、JTAトランザクションを使用していて、JTAトランザクションと組み合わせてセッションを開く/閉じるように休止状態を構成している可能性があります。

于 2012-05-19T11:31:43.013 に答える
0

セッションはセッションプールからのものであり、再利用されるため、フィルターがすべての要求に対してセッションを作成する場合は問題ありません。OSの観点からは、何も起こりません。

休止状態のセッションは、実際には、データベースサーバーへのtcp(またはソケット/パイプ)接続です。db connの作成のコストは、sqlタイプに大きく依存します(postgresqlは、これでは特に悪いですが、すべての点で非常に優れています)。ただし、hibernateはデータベース接続を再利用するため、実際には何の意味もありません。

単純なHibernateフィルターソリューションも、すべてのリクエストに対してセッションで新しいトランザクションを開始します。これはSQLの観点からはトランザクションであり、「BEGIN」および「COMMIT」クエリです。それは常に費用がかかるので、これを減らす必要があります。

IMHOで考えられる解決策は、トランザクションが現在のリクエストの最初のクエリでのみ開始された場合です。多分春はこれに使える何かを持っています。

于 2013-01-16T00:32:26.083 に答える