I need to do some specific action after the successful transaction commit, which basically includes my analytical operations about the data;
I tried using the following code snippet
public class EntityEventHandlers {
private static Logger logger = LoggerFactory.getLogger(EntityEventHandlers.class);
@Autowired
private AsyncEventBus async;
@PostUpdate
public void postUpdate(Order order) {
AutowireHelper.autowire(this, this.async);
logger.debug("post update called " + order.getId());
async.post(new ESCreateOrderEvent(order));
}
@PostPersist
public void postPersist(Order order) {
AutowireHelper.autowire(this, this.async);
logger.debug("post insert called " + order.getId());
async.post(new ESCreateOrderEvent(order));
}
}
But found that by when my the order is not persisted.
Can somebody tell me a better solution where I can trigger some action after transaction commit is successful.
I heard(tried using) about @TransactionEventListener, but didnt see anything triggering.
Updated the source
@Component
public class TXEventHandler {
@TransactionalEventListener
public void doAfterCommit(ApplicationEvent event){
//process here
}
}
About the application Its a Spring MVC based on 4.2.0 and uses Hibernate and MySql as the db.
Right now I have solved the problem by putting the event into a delay queue and the delay is sufficient to happen the db commit. But I know its not a good solution. So let me know if someone have faced this issue and able to fix it.
Thanks In Advance.
Assuming, as your comment mentions, that you are using an entity manager to persist/merge your entity object, you probably have a Bean that wires it in. If so, then in order to take advantage @TransactionalEventListener, you want to wire in ApplicationEventPublisher bean. You class might look like:
@Component
public class OrderManager {
@PersistenceContext
protected EntityManager entityManager;
// You need this Spring bean
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
// ...
@Transactional
public void saveOrder(Order newOrder) {
entityManager.persist(newOrder);
applicationEventPublisher.publishEvent(new OrderEvent());
}
@TransactionalEventListener
public void doAfterCommit(OrderEvent event){
//process here
}
// inner class for brevity, you may not want to do this in practice
public static class OrderEvent {
}
}
This code (although horribly put together in a single class..) is just to illustrate this point: if you want @TransactionalEventListener to trigger, then you need to (at least):
The default behaviour will trigger the TransactionalEventListener after the commit is complete & entity manager is flushed, but still within the bounds of the transaction. You can change this within the annotation with the 'phase' param, but this should be enough to address your issue.
ps. you can glean most of this from https://spring.io/blog/2015/02/11/better-application-events-in-spring-framework-4-2 as JB Nizet says
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With