web-dev-qa-db-ja.com

Springでトランザクションを使用する場合のポストコミットの作成

特定の理由により、Spring PlatformTransactionManagerを使用してトランザクションのコミットとロールバックを手動で実行したため、トランザクションがコミットされた後にコミット後のアクションが実行されるようにフックを設定する必要があります。

見て:

 void commit(TransactionStatus status) throws TransactionException;

トランザクションが成功したと判断する方法がわからないので、例外がスローされない場合は、それを想定する以外に、.

そして、AOPを1つのオプションとして使用することもできますが、おそらくコールバックメソッドを使用して、プログラムでそれを行うことはどうでしょうか?

28
user1555190

TransactionSynchronizationManager および TransactionSynchronization を使用すると、より簡単な方法で正確に目的のものを取得できます。

TransactionSynchronizationManagerを使用すると、現在のトランザクションに関する情報を取得する静的メソッドがあり、TransactionSynchronizationを登録すると、呼び出し時にポストコミットを自動的に実行できます

TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization(){
           void afterCommit(){
                //do what you want to do after commit
           }
})

TransactionSynchronizationはスレッドごとに行われることに注意してください(多くの場合、基本的なWebリクエストでは問題になりません)。

48
Grooveek

Grooveekの答えとその下でのAlexのコメントの功績-結合された提案により、ネット上で見つけるのが難しい堅固でクリーンなソリューションが提供されるため、ここにこれを入れました。

Spring 4以降を使用します。 @Transactionalメソッドが正常にコミットした後でコールバックが必要な場合は、メソッドの先頭に追加します。

@Service
public class OneService {

    @Autowired
    OneDao dao;

    @Transactional
    public void a transactionalMethod() {
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter(){
            public void afterCommit(){
                //do stuff right after commit
                System.out.println("commit!!!");

            }
        });
        //do db stuff
        dao.save();
    }
}
15

特定の理由により、私のプロジェクトの1つで、PlatformTransactionManagerも使用する必要がありました。だから私はorg.springframework.transaction.support.TransactionTemplate

http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/transaction/support/TransactionTemplate.html

主な利点は、PlatformTransactionManagerを正しく実装していれば、手動のコミット/ロールバックに煩わされる必要がないことです。より具体的なものが必要な場合は、少なくともTransactionTemplateのソースコードが役立ちます。

使用するのはかなり簡単です:

config.xml

<bean name="transactionTemplate"
            class="org.springframework.transaction.support.TransactionTemplate">
    <property name="transactionManager" ref="platformTransactionManager"/>
</bean>

MyServiceImpl.Java

 
 @ Service 
パブリッククラスMyServiceImplはMyServiceを実装します{
 
 @Autowired 
 private TransactionTemplate transactionTemplate; 
 
 public Entity getSomethingWithTx(final long id){
 
 return transactionTemplate.execute(new TransactionCallback <Entity>(){
 @Override 
 public Entity doInTransaction(TransactionStatus status){
 // TODO implement 
} 
}); 
} 
 
1
n1ckolas