2012-10-24 13 views
30

私はpropagation = Propagation.REQUIRES_NEWトランザクションの性質を持っている方法があります。このメソッドは、同時に複数回呼び出すことができ、すべてのトランザクションのためにエラーがより発生した場合春のトランザクション:ロールバックトランザクション

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

をロールバックされます(他のトランザクションとは独立して)。

問題は、別のものが利用可能であっても、複数のトランザクションを作成してパフォーマンスの問題を引き起こす可能性があることです。 propagation = Propagation.REQUIRED


Javaのドキュメントは言う:Support a current transaction, create a new one if none exists.

これは、パフォーマンス上の問題を解決すると思われる、ないないそれは?

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

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

私たちは、当社のサーバーに接続しているクライアントの数百を持っています。

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

私がREQUIREDを使用している場合は、1つのトランザクションのみが使用されていますか?100番目のクライアントに問題が発生した場合、第1のクライアントのトランザクションもロールバックされますか?

+1

これは、メソッドが呼び出されるたびに新しいトランザクションを作成するためのREQUIRES_NEWの要点です。はい、あなたが必要な場合、トランザクションがロールバックされ、それはすべてをロールバックします。 –

+0

@DenisTulskiyそのすべての以前の呼び出しは、その関数、または現在の呼び出しスタックですか? –

+2

@jidma:トランザクション全体、@ Eugenの答えを見てください。もし 'createUser'がクライアントコードを呼び出す最初のメソッドなら、REQUIRES_NEWとREQUIREDは同じものです –

答えて

48

使用方法REQUIRES_NEWは、メソッドがトランザクションコンテキストから呼び出された場合にのみ関係します。メソッドが非トランザクションコンテキストから呼び出されると、それは正確にREQUIREDとして振る舞います - それは新しいトランザクションを作成します。

これは、すべてのクライアントに対して1つのトランザクションが1つしかないことを意味するものではありません。つまり、各クライアントは非トランザクションコンテキストから開始し、要求処理が@Transactionalに達すると、トランザクション。

したがって、REQUIRES_NEWを使用すると、その操作のセマンティクスには意味があります。パフォーマンスについては心配しないでください。これは教科書の時期尚早な最適化です。正確性とデータの完全性を重視し、パフォーマンスについて心配しますパフォーマンス指標が収集されると、それ以前にはなくなります。

ロールバック時 - REQUIRES_NEWを使用すると、強制的に新しいトランザクションが開始され、そのトランザクションはロールバックされます。例外が実行されたかどうかに応じてロールバックされるトランザクションもあります。これは、操作の詳細に基づいて選択したものです。 さらに、トランザクション戦略とロールバックの詳細については、«Transaction strategies: Understanding transaction pitfalls», Mark Richardsをお勧めします。

+0

この問題をご覧になれますかhttps://stackoverflow.com/questions/44539861/spring-transactional-commit-failures-deby-eclipselink? 私は 'REQUIRES_NEW'を必要としますか?後で返された応答は、後でPesistがロールバックされた後に返されます。 – vels4j

10

実際に別のトランザクションで実行する必要がある場合は、REQUIRES_NEWを使用し、パフォーマンスのオーバーヘッドを生かす必要があります。デッドロックに注意してください。 Java側の

  • 検証データ:

    は、私はむしろそれを他の方法にしてください。

  • 1つのトランザクションですべてを実行します。
  • DB側で何かがうまくいかない場合は、DBや検証設計の重大なエラーです。すべてをロールバックし、重大なトップレベルのエラーを投げます。
  • 良い単位テストを書く。
+0

私たちは何百ものクライアントをサーバに接続しています。クライアントごとに、トランザクションに関するフィードバックを送信する必要があります(OKまたは例外 - >ロールバック)。私の質問は残っています:もし私が 'REQUIRED'を使っているのであれば、1つのトランザクションしか使われていないのでしょうか?そして100番目のクライアントが問題に遭遇した場合、最初のクライアントのトランザクションはロールバックされますか? –

関連する問題