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"/>

приложение использует некоторые внешние веб-службы, которые необходимо "очистить", когда внутренняя транзакция получает откат. Есть ли способ сделать это без использования декларативного управления транзакциями.

3 ответов


  • из спящего режима вы можете расширить EmptyInterceptor и переопределить afterTransactionCompletion() метод и зарегистрируйте его в SessionFactoryBean или HibernateTransactionManager.

  • от весны вы смогли удлиняет TransactionSynchronizationAdapter и переопределить afterCompletion() и регистрация при необходимости с TransactionSynchronizationManager#registerSynchronization().

редактировать

пример использования Spring Aop для добавления синхронизации ко всем методам, аннотированным @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 
    }
}

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

инфраструктура обработки событий, введенная весной 4.2, делает это намного проще.

посмотреть:

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

еще один популярный улучшение-это способность связывать слушателя событие для фазы транзакции. Типичный пример-ручка событие, когда транзакция успешно завершена

@Component
public class MyComponent {

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

}

@TransactionalEventListener обычный @EventListener, а также предоставляет TransactionPhase, значение по умолчанию AFTER_COMMIT. Вы можете также подключайте другие фазы транзакции (BEFORE_COMMIT, AFTER_ROLLBACK и AFTER_COMPLETION это просто псевдоним для AFTER_COMMIT и AFTER_ROLLBACK).


использование Spring 4+: Самый простой / чистый способ без использования глобальных аспектов и конфигураций основан на моем ответе здесь:https://stackoverflow.com/a/43322052/986160

Если вам нужен обратный вызов на @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();
    }
}