ねえ、私は 4 層のソフトウェア システム (プレゼンテーション - JSP、問題ドメイン、アプリケーション ロジック、永続性) を構築しており、何かをしたいたびにトランザクションを作成しないように、リクエストごとにトランザクションを休止状態にしたいと考えています。と ...
リクエストごとに 1 つのトランザクションを維持するために ClickServlet を使用しているときに、4 つの抽象化レイヤーを使用してアプリケーションを作成する方法に興味があります。私の知る限り、トランザクションは、アクティブなサーブレット ワーカー スレッドと同じ数のリクエストになります。
Hibernate の遅延読み込み機能を利用する場合は、次のいずれかを行います。
(1)リクエストがまだアクティブなときにトランザクションを維持する必要がある(LazyLoadingExceptionを取得しないようにするため)、または
(2)レイヤーを分離し、Hibernateモデルを上のレイヤーに渡す代わりに、レイヤーにDTOとVOを渡すようにする必要があります。
IMO後者はよりクリーンなアプローチです。抽象化レイヤーを持つ主な目的は、再利用しやすく、テストしやすくし、懸念を分離することです。
サーブレット セッション/リクエスト レベルでトランザクションを処理しないことをお勧めします。これにより、プレゼンテーションの下のすべてのレイヤーがサーブレット API と密接に結合されます。通常、これは、抽象化レイヤーが必要な場合に必要なことではありません。したがって、おそらく Apache Click フレームワークとその ClickServlet は、最適な方法ではありません。春はそれをうまく処理できます。拒否された場合は、残念です。
Spring 自動トランザクションを使用したくない場合でも、AspectJ (または他のアスペクト指向プログラミング コンポーネント) を使用してトランザクションを透過的に処理できます (メソッドに入るときにトランザクションを作成し、メソッドを終了するときにコミット/ロールバックします)。もちろん、これは単に Spring Framework を採用するだけではありません。
... また、変更されたプロパティのみが更新されるように、オブジェクトを使用してデータを追跡することもできます。
これは、Hibernate Level 1 Cache + Lazy Loading によって透過的に処理できます。自分でやる必要はありません。Hibernate は、セッションがフラッシュされているとき、L1 キャッシュがいっぱいのとき、またはトランザクションのコミット時にのみ、バックエンドに SQL を生成します。一般に、バックエンドへのデータ操作言語 (DML) ステートメントを最小限に抑えるために何もする必要はありません。通常、Hibernate は適切に構成されている場合、これをより適切に処理します。
JTA も調べましたが、Bean を使用していないため、JTA がどのように役立つかわかりません。
Bean なしで JPA を使用できます。これは、どこからでも呼び出すことができる単純な API です。
トランザクションを閉じたり開いたりするために呼び出すメソッドを持つなどの解決策を考えましたが、もっと洗練された解決策があるようです。
はい。Gregor Kiczales によるアスペクト指向プログラミングを見てください。Spring Framework は、この AOP を既製でサポートしています。あなたのチームがそれを拒否した場合でも、自分で行うことができます。
私のシステムに基づいて、リクエストごとにトランザクションを維持する最良の方法は何ですか?
最善のアプローチ (4 つの抽象化レイヤーを持つことを計画していることを確認) は、データを Hibernate ドメイン モデルから永続レイヤーのデータ転送オブジェクト/値オブジェクトにロードすることです。上のレイヤーであるアプリケーション ロジック レイヤーは、Hibernate ドメイン モデルにアクセスできますが、Hibernate モデルを上のレイヤーに渡すことはできません。効率的にするには、これらのレイヤーにページネーションを実装する必要があります (そうしないと、多くの場合、すべてのデータがメモリにロードされてしまいます)。
このように、トランザクションのアスペクト化と相まって、現在のベスト プラクティスだと思います。