- I have this application where the controller is called and it does some database operations and commit them after the end of controller cycle of spring
- Also in this controller itself we raise one async event which requires the data that we are persisting in the database while execution of controller.
- Since the data is not persisted yet in db we cannot access it in our async event while the controller is still executing.
What I want is, execution of this async event should start after the execution of controller itself is it possible to do so in spring?
CodePudding user response:
Use the annotation @TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION) to define an event listener that fires after the completion of the transaction in the database:
@Component
public class TransactionEventListener {
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION)
public void afterCompletion(PayloadApplicationEvent<EventData> event) {
System.out.println("Event data: " event.getPayload().data);
}
}
Publish the event after saving the data using ApplicationEventPublisher. Note the method must be annotated with @Transactional because the transaction is required to fire the event.
@Autowired
private DataRepo dataRepo;
@Autowired
private ApplicationEventPublisher publisher;
@Async
@Transactional
public void storeData() {
...
dataRepo.save(data);
publisher.publishEvent(eventData);
...
}
CodePudding user response:
you can use spring aop to do this. If you're using spring boot, you can add @EnableAspectJAutoProxy to one of your configuration class, then create a aspect for your controller method:
@Aspect
@Component
public class SomeAspect {
@Pointcut("execution(* org.demo..controller.SomeController.someMethod(..))")
private void someMethodJointcut(){}
@After("someMethodJointcut()")
public void doAfter(JoinPoint joinPoint) {
//use joinPoint.getArgs() get parameters that passed to the controller
//call your async method here
}
}
Use around advice if you need to access the execution result of the controller call.
