web-dev-qa-db-ja.com

Spring @Transactional(propagation = Propagation.SUPPORTS)をいつ使用するか?

Springjavadocによると@Transactional(propagation = Propagation.SUPPORTS)

現在のトランザクションをサポートし、存在しない場合は非トランザクションで実行します。同じ名前のEJBトランザクション属性に類似しています。

私はメソッドを非トランザクションで宣言し、それで済ませることができるようですので、私の質問はそうです。

  • SUPPORTSの伝播が必要な状況は何ですか?
  • サポート伝播のポイントは何ですか?

SUPPORTSが実際に役立った実際の例/シナリオを誰かに教えてもらえますか?

19
ams

私が考えることができる最も簡単な例は、JMSサーバーにコンテンツを送信するメソッドです。トランザクションのコンテキストにいる場合は、メッセージをトランザクションスコープに結合する必要があります。しかし、まだ実行中のトランザクションがない場合は、トランザクションサーバーも呼び出して、1回限りのメッセージを実行するためだけにトランザクションサーバーを起動するのはなぜですか?

これらは、実装だけでなくAPIでも宣言できることを忘れないでください。そのため、ユースケースに配置することと何も配置しないことで大きな違いがない場合でも、API作成者がトランザクションに含めることができる操作を指定することは、おそらく呼び出す操作とは対照的に、付加価値があります。トランザクションに参加しない外部システム。

もちろん、これはJTAのコンテキストです。この機能は、トランザクションがリソースローカルの物理データベーストランザクションに制限されているシステムでは、実際にはあまり実用的ではありません。

7
Affe

これは、特にORMが使用されている場合に、選択操作でreadOnly=trueトランザクションフラグと一緒に適切なペアになります。

@Transactional(readOnly = true, propagation=Propagation.SUPPORTS)
public Pojo findPojo(long pojoId) throws Exception {
   return em.find(Pojo.class, pojoId);
}

この場合、選択操作を実行するためだけのトランザクションがまだない場合は、新しいトランザクションを作成するための料金を支払わないようにしてください。

すでにその思考プロセスに参加している場合は、トランザクションの側面をすべて一緒に捨てることを検討することもできます。

public Pojo findPojo(long pojoId) throws Exception {
   return em.find(Pojo.class, pojoId);
}
4
dimitrisli

この問題によると readOnly操作のPropagation.SUPPORTSでパフォーマンスを向上させる Propagation.SUPPORTSで読み取り専用トランザクションを設定しないでください:

この変更によって実際にパフォーマンスが向上するかどうかは決して明らかではありません。これには複数の側面があります。それらの最初は、リンクされた記事が古く、物事を積極的に単純化するため、信じられないほど欠陥があるということです。必要に応じて詳細を説明しますが、とりあえずそのままにしておきます。ここでは、実行パフォーマンスに影響を与えることがたくさんあります。トランザクションが進行中でない場合、readOnlyフラグがJDBCドライバーに伝播されず(多くのデータベースの最適化が適用されない原因になります)、フラッシュを明示的にオフにするなど、SpringのJPAリソース管理コードで最適化を適用しません。適用-大量のデータを読み取る場合、パフォーマンスを劇的に向上させることができます。

0
Grigory Kislin