Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 927
Josef Procházka Avatar asked May 14 '14 10:05

Josef Procházka


People also ask

How Hibernate handle multiple transactions?

Therefore, you can run multiple transactions on the same Hibernate Session, but there's a catch. Once an exception is thrown you can no longer reuse that Session. My advice is to divide-and-conquer. Just split all items, construct a Command object for each of those and send them to an ExecutorService#invokeAll .

Does @transactional rollback?

The @Transactional annotation makes use of the attributes rollbackFor or rollbackForClassName to rollback the transactions, and the attributes noRollbackFor or noRollbackForClassName to avoid rollback on listed exceptions. The default rollback behavior in the declarative approach will rollback on runtime exceptions.

When should we use @transactional annotation?

The @Transactional annotation belongs to the Service layer because it is the Service layer's responsibility to define the transaction boundaries.


2 Answers

  • 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 
    }
}
like image 79
Jose Luis Martin Avatar answered Sep 17 '22 20:09

Jose Luis Martin


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).

like image 42
Alan Hay Avatar answered Sep 17 '22 20:09

Alan Hay