web-dev-qa-db-ja.com

Spring hibernate、トランザクションのコミットまたはトランザクションのロールバック後にメソッドを呼び出す方法

トランザクションが成功またはロールバックした後、いくつかのメソッドを呼び出す必要があります。私はとして使用しています

    <bean name="openSessionInViewInterceptor" class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
                <property name="sessionFactory">
                    <ref local="mysessionFactory"/>
                </property>
    </bean>

    <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory">
            <ref local="mysessionFactory"/>
        </property>
    </bean>

<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>

アプリケーションは、内部トランザクションがロールバックされたときに「クリーンアップ」する必要があるいくつかの外部Webサービスを使用します。宣言型トランザクション管理を使用せずにこれを達成する方法はありますか?.

11
  • Hibernateから、EmptyInterceptorを拡張してafterTransactionCompletion()メソッドをオーバーライドし、それをSessionFactoryBeanまたはHibernateTransactionManagerに登録できます。

  • Springからは、TransactionSynchronizationAdapterを拡張してafterCompletion()をオーバーライドし、必要に応じてTransactionSynchronizationManager#registerSynchronization()に登録できます。

編集

SpringAopを使用して@Transactionalアノテーションが付けられたすべてのメソッドに同期を追加する例

@Aspect
class TransactionAspect extends TransactionSynchronizationAdapter {

    @Before("@annotation(org.springframework.transaction.annotation.Transactional)")
    public void registerTransactionSyncrhonization() {
        TransactionSynchronizationManager.registerSynchronization(this);

    }

    @Override
    public void afterCompletion(int status) {
        // code 
    }
}
26

Springには、ここで興味深いと思われるさまざまなクラスがあります。

http://docs.spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/transaction/support/TransactionSynchronization.html

http://docs.spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/transaction/support/TransactionSynchronizationAdapter.html

http://docs.spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/transaction/support/TransactionSynchronizationManager.html

ここにいくつかのサンプルコードがあります:

http://azagorneanu.blogspot.co.uk/2013/06/transaction-synchronization-callbacks.html


2016年の更新

Spring 4.2で導入されたイベント処理インフラストラクチャにより、これがはるかに簡単になります。

見る:

https://spring.io/blog/2015/02/11/better-application-events-in-spring-framework-4-2#transaction-bound-events

もう1つの一般的な改善点は、イベントのリスナーをトランザクションのフェーズにバインドする機能です。典型的な例は、トランザクションが正常に完了したときにイベントを処理することです。

@Component
public class MyComponent {

  @TransactionalEventListener(condition = "#creationEvent.awesome")
  public void handleOrderCreatedEvent(CreationEvent<Order> creationEvent) { 
    ...
  }

}

@TransactionalEventListenerは通常の@EventListenerまた、TransactionPhaseを公開します。デフォルトはAFTER_COMMITです。トランザクションの他のフェーズ(BEFORE_COMMIT、AFTER_ROLLBACK、およびAFTER_COMMITとAFTER_ROLLBACKの単なるエイリアスであるAFTER_COMPLETION)をフックすることもできます。

18
Alan Hay

Spring 4+の使用:グローバルな側面と構成を使用しない最も簡単でクリーンな方法は、ここでの私の答えに基づいています: https://stackoverflow.com/a/43322052/98616

正常にコミットした後に@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();
    }
}
11