Spring @TransactionalEventListener没有按预期工作

时间:2016-06-23 02:50:27

标签: spring spring-transactions

我正在尝试使用@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。请指导我。

3 个答案:

答案 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中,它仅适用于单线程应用程序

相关问题