我正在尝试使用@TransactionalEventListener监听事件,但事件在整个事务结束之前都会被侦听。即使方法抛出异常,也会监听该事件。
以下是我正在尝试做的示例代码
@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
}
}
在这种情况下,我的侦听器会在我的事务方法中完成插入后立即调用。我相信在所有DB调用结束并且提交完成后应该调用它。我错过了什么。我使用的是Spring 4.3.0。请指导我。
答案 0 :(得分:3)
我想出了这个问题。如果您不使用Spring MVC,则不会发生此问题。由于在rootapplicationcontext和子webapplicationcontext(对于Spring MVC)中加载了侦听器类,因此发生此问题。
我在application-context.xml和spring-web.xml中都进行了通用组件扫描。因此,监听器类加载了两次。一次为application-context.xml,另一次为spring-web.xml。在spring-web.xml中删除通用组件扫描并仅提及控制器包和过滤器包时,问题得到了解决。
事务事件侦听器在提交事务后仅被调用一次。
答案 1 :(得分:2)
TransactionalEventListener可以侦听不同的TransactionPhase。您可以在注释中指定不同的阶段。在您的情况下, AFTER_COMMIT 或 AFTER_COMPLETION 可能会有用。
答案 2 :(得分:0)
Thre问题是TransactionalEventListener实现中的一个错误。它检查事件处理执行程序的线程上的TransactionSynchronizationManager.isSynchronizationActive(),但是在另一个线程(tomcat线程池,jetty线程池等)上创建了事务。因此在Spring 4.2中,它仅适用于单线程应用程序