web-dev-qa-db-ja.com

クラス全体のトランザクションアノテーション+単一のメソッドを除く

@Transactionalアノテーションが付いたクラスがあります(すべてのメソッドにマークを付ける代わりに)。

そのクラス内に@Transactionalとして注釈を付けるべきではない単一のメソッドがありますが。

私の質問は、このメソッドに「非トランザクション」としてマークするために配置できるアノテーションはありますか?または、このクラスの各単一メソッドを、このメソッドを除いて「トランザクション」としてマークし始める必要があります(多くの作業)

ありがとう。

20
Urbanleg

使用するさまざまなトランザクション伝播戦略があります。これらは列挙型Propagationに存在します。あなたが使いたいと思うかもしれないものは

/**
 * Execute non-transactionally, suspend the current transaction if one exists.
 * Analogous to EJB transaction attribute of the same name.
 * <p>Note: Actual transaction suspension will not work on out-of-the-box
 * on all transaction managers. This in particular applies to JtaTransactionManager,
 * which requires the {@code javax.transaction.TransactionManager} to be
 * made available it to it (which is server-specific in standard J2EE).
 * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
 */
NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),

/**
 * Execute non-transactionally, throw an exception if a transaction exists.
 * Analogous to EJB transaction attribute of the same name.
 */
NEVER(TransactionDefinition.PROPAGATION_NEVER), // maybe not this one

したがって、クラス内のメソッドにこれらのいずれかでアノテーションを付けます。

@Transactional
public class MyTransactionalClass { 
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void nonTransactionalMethod() {...}
}

あなたはすべての伝播戦略を見つけることができます ここ

29

6年前の質問に答えて申し訳ありませんが、受け入れられた答えが実際には質問に答えていないことに気づきました。問題は、メソッドに_@Transactional_アノテーションがまったく付いていないかのように動作させる方法でした。このようなメソッドは、トランザクションがある場合はトランザクションに参加し、ない場合は非トランザクションで実行されます。既存のトランザクションを一時停止したり、トランザクションが存在する場合は実行を拒否したりすることはありません。その1つは、受け入れられた回答の結果です。

使用する伝播は_Propagation.SUPPORTS_です(言い換えると、メソッドに@Transactional(propagation = SUPPORTS)アノテーションを付けます。これは、トランザクションが存在する場合はトランザクションに参加し、存在しない場合は非トランザクションと同様に非トランザクションで実行されます。 -注釈付きのメソッドはそうします。

Javadocによると、それは_@Transactional_アノテーションがまったくないのと同じではありません正確に。それは言う:

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

注:トランザクション同期を使用するトランザクションマネージャーの場合、SUPPORTSは、同期が適用されるトランザクションスコープを定義するため、トランザクションがまったくない場合とは少し異なります。結果として、同じリソース(JDBC接続、Hibernateセッションなど)が指定されたスコープ全体で共有されます。これは、トランザクションマネージャーの実際の同期構成に依存することに注意してください。

メソッドを動作させる唯一の方法exacty _@Transactional_でアノテーションが付けられていないかのように、OPが提案するように行うことです。クラスにアノテーションを付けないで、他のすべてのメソッドにアノテーションを付けます。 、ただし、ほとんどの用途では必要ではなく、_Propagation.SUPPORTS_を使用するだけで十分です。

1
Pepijn Schmitz