62

propagation = Propagation.REQUIRES_NEWトランザクション プロパティを持つメソッドがあります。

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void createUser(final UserBean userBean) {
    //Some logic here that requires modification in DB
}

このメソッドは同時に複数回呼び出すことができ、エラーが発生した場合はすべてのトランザクションに対して (他のトランザクションから独立して) ロールバックされます。

問題は、別のトランザクションが利用可能であっても、Spring が複数のトランザクションを作成することを余儀なくされ、パフォーマンス上の問題が発生する可能性があることです。


の Java doc は次のようにpropagation = Propagation.REQUIRED述べています。Support a current transaction, create a new one if none exists.

これでパフォーマンスの問題は解決したようですね。

ロールバックの問題はどうですか?既存のトランザクションの使用中に新しいメソッド呼び出しがロールバックした場合はどうなりますか? 以前の呼び出しでさえ、トランザクション全体をロールバックしませんか?

[編集] 私の質問は十分に明確ではなかったと思います:

サーバーには何百ものクライアントが接続されています。

クライアントごとに、トランザクションに関するフィードバックを送信する必要があります (OK または例外 -> ロールバック)。

私の質問は次のとおりです。使用する場合REQUIRED、1 つのトランザクションのみが使用されるということですか。100 番目のクライアントで問題が発生した場合、最初のクライアントのトランザクションもロールバックされますか?

4

2 に答える 2

97

UsingREQUIRES_NEWは、メソッドがトランザクション コンテキストから呼び出された場合にのみ関連します。メソッドが非トランザクション コンテキストから呼び出されると、まったく同じように動作REQUIREDし、新しいトランザクションが作成されます。

これは、すべてのクライアントに対して 1 つのトランザクションしか存在しないという意味ではありません。各クライアントは非トランザクション コンテキストから開始され、リクエスト処理が に到達するとすぐに@Transactional、新しいトランザクションが作成されます。

したがって、それを念頭に置いて、使用REQUIRES_NEWがその操作のセマンティクスにとって理にかなっている場合-パフォーマンスについて心配しないよりも-これは教科書の時期尚早の最適化になります-私はむしろ正確性とデータの整合性を強調し、パフォーマンスメトリックがいったん調整されたらパフォーマンスについて心配します以前ではなく、収集されました。

ロールバック時 - を使用REQUIRES_NEWすると、新しいトランザクションが強制的に開始されるため、例外によってそのトランザクションがロールバックされます。同様に実行されていた別のトランザクションもある場合、例外がスタックをバブルアップするかキャッチされるかによってロールバックされるかどうかに応じて、操作の詳細に基づいて選択します。また、トランザクション戦略とロールバックに関するより詳細な議論については、「トランザクション戦略: トランザクションの落とし穴を理解する」、Mark Richardsをお勧めします。

于 2012-10-24T15:46:39.913 に答える
13

本当に別のトランザクションでそれを行う必要がある場合はREQUIRES_NEW、パフォーマンスのオーバーヘッドを使用して対処する必要があります。デッドロックに注意してください。

私はむしろ他の方法でそれをしたい:

  • Java 側でデータを検証します。
  • すべてを 1 つのトランザクションで実行します。
  • DB側で何か問題が発生した場合→DBまたはバリデーション設計の重大なエラーです。すべてをロールバックし、重大な最上位エラーをスローします。
  • 適切な単体テストを作成します。
于 2012-10-24T14:37:44.980 に答える