Spring MVCのコントローラを@Transactionalにしない方がいい理由とは?
疑問点
このトピックに関する質問はすでにいくつかありますが、Spring MVCコントローラを作るべきではない理由を説明するための議論を提供してくれる回答はまったくありません。
Transactional
. 見てください。
では、なぜ?
- はあるのでしょうか? 乗り越えられない 技術的な問題はありますか?
- アーキテクチャ上の問題はありますか?
- パフォーマンス/デッドロック/同時実行の問題はありますか?
- 複数の個別のトランザクションが必要な場合がありますか?もしそうなら、どのようなユースケースがありますか?(サーバーへの呼び出しが完全に成功するか、完全に失敗するかのどちらかであるという単純化されたデザインが好きです。それは非常に安定した動作に聞こえます)
背景 私は数年前、C#/NHibernate/Spring.Net で実装された非常に大規模な ERP ソフトウェアのチームで働いていました。サーバーへのラウンド トリップは、まさにそのように実装されていました。トランザクションは、任意のコントローラ ロジックに入る前に開かれ、コントローラを終了した後にコミットまたはロールバックされました。トランザクションはフレームワークで管理され、誰もそれを気にする必要はありませんでした。 安定していて、シンプルで、数人のアーキテクトだけがトランザクションの問題を気にする必要があり、残りのチームは機能を実装するだけでよかったのです。
私の観点では、これは私がこれまで見た中で最高のデザインです。Spring MVC で同じ設計を再現しようとすると、遅延ロードとトランザクションの問題で悪夢を見ることになり、毎回同じ答えが返ってきました。
あなたの設立された回答を事前にありがとうございました
どのように解決するのですか?
TLDR : これは、アプリケーションのサービス層だけが、データベース/ビジネストランザクションの範囲を特定するために必要なロジックを持つためです。設計上、コントローラーと永続化層はトランザクションのスコープを知ることはできませんし、知るべきではありません。
コントローラは
@Transactional
にすることもできますが、実際にはサービス層のみをトランザクションにすることが一般的な推奨事項です(永続化層もトランザクションにすべきではありません)。
この理由は、技術的な実現可能性ではなく、関心事の分離です。コントローラの責任は、パラメータリクエストを取得し、1つまたは複数のサービスメソッドを呼び出し、結果をレスポンスにまとめ、クライアントに送り返すことです。
つまり、コントローラはリクエスト実行の調整役と、ドメインデータをクライアントが消費できる形式(DTOなど)に変換する機能を持つのです。
ビジネスロジックはサービス層に存在し、永続化層はデータベースとの間でデータを取得/保存するだけです。
口座振替では、他方が入金されている場合のみ口座が引き落とされるなど、ビジネスロジックを含むサービス層のみが銀行口座振替のトランザクションの範囲を実際に知ることができます。
永続化レイヤーはどのようなトランザクションであるかを知ることができません、例えば、メソッド
customerDao.saveAddress
. このメソッドは常に別のトランザクションで実行されるべきなのでしょうか。時にはそれは別のトランザクションで実行されるべきですし、時には
saveCustomer
が動作した場合のみデータを保存する、などです。
同じことがコントローラにも当てはまります。
saveCustomer
と
saveErrorMessages
が同じトランザクションに入るのですか?あなたは、顧客を保存し、それが失敗した場合、いくつかのエラーメッセージを保存し、データベースに保存したいエラーメッセージを含むすべてをロールバックするのではなく、適切なエラーメッセージをクライアントに返すようにしたいと思うかもしれません。
非トランザクションコントローラでは、サービス層から返されるメソッドは、セッションが終了しているため、切り離されたエンティティを返します。これは正常な動作で、解決策としては
OpenSessionInView
を使用するか、コントローラが必要とする結果を熱心に取得するクエリを実行することです。
とはいえ、コントローラをトランザクションにすることは罪ではありません。
関連
-
強制型変換について
-
keytool error: java.io.FileNotFoundException: cacerts (アクセス拒否されました。)
-
Javaがエラーで実行される、選択が起動できない、最近起動したものがない
-
Zipファイルの圧縮・解凍にantを使用する
-
[解決済み] Spring @Transactional - 分離、伝搬
-
[解決済み] ASP.NET MVCコントローラは、Imageを返すことができますか?
-
[解決済み] Spring MVCの@ModelAttributeとは何ですか?
-
[解決済み] springの@Controllerアノテーションと@RestControllerアノテーションの違いについて
-
[解決済み】Spring - @Transactional - バックグラウンドで何が起こっているのか?
-
[解決済み] Spring MVCの型変換:PropertyEditorかConverterか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Eclipseは、ポップアップA Java Exception has occurred.を実行し、エラーException in threadの解決策を報告します。
-
NullPointerException - java.lang.
-
[解決済み] Spring Boot の spring.jpa.open-in-view=true というプロパティは何ですか?
-
undefined[sonar] sonar:デフォルトのスキャンルール
-
javaの非静的メソッドを静的に参照することができない
-
SLF4J: クラス・パスに複数のSLF4Jバインディングが含まれています。
-
Jsoup-Crawlingの動作
-
-bash: java: コマンドが見つからない 解決方法
-
Javaがリソースリークに遭遇した:'input'が閉じない 解決方法
-
コンストラクタDate()が未定義である問題