Spring @TransactionalEventListener 未按预期工作
Spring @TransactionalEventListener not working as expected
我正在尝试使用@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
}
}
在这种情况下,只要在我的事务方法中插入完成,就会调用我的侦听器。我相信这应该在所有数据库调用结束并且提交完成后被调用。我错过了什么吗?我正在使用 Spring 4.3.0。请指导我。
TransactionalEventListener 可以监听不同的 TransactionPhase。您可以在注释中指定不同的阶段。在您的情况下,AFTER_COMMIT 或 AFTER_COMPLETION 可能会有用。
我想通了这个问题。如果您不使用 Spring MVC,则不会发生此问题。发生此问题的原因是侦听器 class 同时加载到 rootapplicationcontext 和子 webapplicationcontext(对于 Spring MVC)。
我在我的应用程序-context.xml 和spring-web.xml 中都进行了通用组件扫描。因此,侦听器 class 被加载了两次。一次用于应用程序-context.xml,一次用于spring-web.xml。在删除 spring-web.xml 的通用组件扫描并仅提及 spring-web.xml 中的控制器包和过滤器包时,问题得到解决。
事务事件侦听器在事务提交后仅被调用一次。
第三个问题是 TransactionalEventListener 实现中的错误。它检查事件处理执行器线程上的 TransactionSynchronizationManager.isSynchronizationActive(),但事务是在另一个线程(tomcat 线程池、jetty 线程池等)上创建的。所以在 Spring 4.2 中它只在单线程应用程序中工作正常
我正在尝试使用@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
}
}
在这种情况下,只要在我的事务方法中插入完成,就会调用我的侦听器。我相信这应该在所有数据库调用结束并且提交完成后被调用。我错过了什么吗?我正在使用 Spring 4.3.0。请指导我。
TransactionalEventListener 可以监听不同的 TransactionPhase。您可以在注释中指定不同的阶段。在您的情况下,AFTER_COMMIT 或 AFTER_COMPLETION 可能会有用。
我想通了这个问题。如果您不使用 Spring MVC,则不会发生此问题。发生此问题的原因是侦听器 class 同时加载到 rootapplicationcontext 和子 webapplicationcontext(对于 Spring MVC)。
我在我的应用程序-context.xml 和spring-web.xml 中都进行了通用组件扫描。因此,侦听器 class 被加载了两次。一次用于应用程序-context.xml,一次用于spring-web.xml。在删除 spring-web.xml 的通用组件扫描并仅提及 spring-web.xml 中的控制器包和过滤器包时,问题得到解决。
事务事件侦听器在事务提交后仅被调用一次。
第三个问题是 TransactionalEventListener 实现中的错误。它检查事件处理执行器线程上的 TransactionSynchronizationManager.isSynchronizationActive(),但事务是在另一个线程(tomcat 线程池、jetty 线程池等)上创建的。所以在 Spring 4.2 中它只在单线程应用程序中工作正常