简体   繁体   中英

Spring hibernate , how to call some method after transaction commit or transaction rollback

I need to call some method after transaction succes or rollback. I am using as

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

The application use some external web services which needs to be "cleaned" when the internal transaction gets rollbacked. Is there way how to accomplish this without using declarative transaction management.

  • From Hibernate, you could extends EmptyInterceptor and override afterTransactionCompletion() method and register it in SessionFactoryBean or HibernateTransactionManager .

  • From Spring you could extends TransactionSynchronizationAdapter and override afterCompletion() and register when appropriate with TransactionSynchronizationManager#registerSynchronization() .

Edit

An Example of using Spring Aop to add a synchronization to all methods annotated with @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 has various classes which might be of interest here:

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

There's some example code here:

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


Update 2016

The event handling infrastructure introduced in Spring 4.2 makes this much simpler.

See:

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

Another popular improvement is the ability to bind the listener of an event to a phase of the transaction. The typical example is to handle the event when the transaction has completed successfully

@Component
public class MyComponent {

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

}

@TransactionalEventListener is a regular @EventListener and also exposes a TransactionPhase, the default being AFTER_COMMIT. You can also hook other phases of the transaction (BEFORE_COMMIT, AFTER_ROLLBACK and AFTER_COMPLETION that is just an alias for AFTER_COMMIT and AFTER_ROLLBACK).

Using Spring 4+: The easiest/cleanest way without using global aspects and configurations is based on my answer here: https://stackoverflow.com/a/43322052/986160

If you need a callback on a @Transactional method after it successfully commits just add that in the beginning of the method:

@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();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM