Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring @TransactionalEventListener not working as expected

I am trying to listen to an event using @TransactionalEventListener but the event gets listened even before the entire transaction is over. The event is listened even if the method throws exception.

Here is the sample code of what i am trying to do

@Component
public class SampleListener{

    @TransactionalEventListener
    public void handleSomeTransactionalEvent(SampleEvent event){
      //Some Logic
    }
}

@Service
@Transactional
public class SampleInsertService{

     @Autowired
     private ApplicationEventPublisher applicationEventPublisher;

     public void someTransactionalMethod(SomeDTO someDTO){
          //Delete all call

          //Again Insert all calls

          //Publish event after insert
          applicationEventPublisher.publishEvent(new SampleEvent(this, String.EventType, someDTO));

          /** Some other call to DB which throws exception **/
     }

}


public class SampleEvent implements ApplicationEvent{

     private String eventType;

     public SampleEvent(Object source, String eventType, SampleDTO sampleDTO){
           //some logic
     }

}

In this scenario, my listener is getting called as soon as insert is complete in my transaction method. I believe this should get called after all DB calls are over and commit is complete. Am I missing something. I am using Spring 4.3.0. Please guide me on this.

like image 937
tejaswini Avatar asked Mar 12 '23 22:03

tejaswini


2 Answers

I figured out the issue. This issue would not occur if you are not using Spring MVC. This issue occurred due to the listener class loaded both in rootapplicationcontext and the child webapplicationcontext(for Spring MVC).

I had given a generic component scan in both my application-context.xml and spring-web.xml. Hence, the listener class got loaded twice. Once for the application-context.xml and again for the spring-web.xml. On removing generic component scan for spring-web.xml and mentioning only controller packages and filter packages in spring-web.xml, the issue got resolved.

The transactional event listener got called only once after commit of the transaction.

like image 91
tejaswini Avatar answered May 16 '23 09:05

tejaswini


TransactionalEventListener can listen on different TransactionPhase. You can specify different phase in your annotation. In your case AFTER_COMMIT or AFTER_COMPLETION might be useful.

like image 43
Shawn Song Avatar answered May 16 '23 09:05

Shawn Song