首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么我的Spring @EventListener在事件提交时表现出与被直接调用时不同的事务行为?

Spring的@EventListener注解用于监听并处理应用中的事件。它可以在事件发布时自动触发相关的事件处理方法。然而,当使用@EventListener处理事件时,有时会观察到与直接调用方法时不同的事务行为。

这个问题的根本原因在于Spring事务管理机制的工作方式。在Spring中,事务通常由PlatformTransactionManager接口及其实现类来管理。默认情况下,Spring在执行带有@EventListener注解的方法时,会使用当前线程的事务上下文来确定是否开启新的事务,或者加入已存在的事务中。

当一个事件被发布时,Spring会创建一个代理对象来执行相关的事件处理方法。这个代理对象会在一个新的事务中执行事件处理方法,并在方法执行完毕后提交事务。这意味着,如果事件处理方法中抛出了一个未被捕获的异常,事务将回滚,包括事件的发布者所在的事务。

这种与直接调用方法不同的事务行为是出于设计考虑的。当一个事件处理方法被声明为@Transactional时,我们期望它在独立的事务中执行,以保证数据的一致性和完整性。这样做的好处是,即使在处理过程中发生异常,只有事件处理方法所在的事务会被回滚,而不会影响到事件的发布者。

对于需要在事件处理方法中使用事务的场景,可以在方法上添加@Transactional注解来明确指定事务行为。例如:

代码语言:txt
复制
@Transactional
@EventListener
public void handleEvent(SomeEvent event) {
    // 事件处理逻辑
}

需要注意的是,@Transactional注解需要与@EventListener注解一起使用,以确保事件处理方法在独立的事务中执行。

推荐的腾讯云相关产品:云原生容器服务 Tencent Kubernetes Engine(TKE),产品介绍链接地址:https://cloud.tencent.com/product/tke

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

DDD落地之事件驱动模型

最开始不了解DDD时候,就觉得事件驱动模型能够非常好解耦系统功能。当然,这个是比较菜,接触DDD之后才开始对事件驱动模型做深度应用了解。...那为什么要改呢? 原因是,业务需求不断迭代过程中,当前业务非强相关主流程业务,随时都有可能替换或者升级。...我们可以从命名上直接看出,它就是个EventListenerSpring4.2+,有一种叫做@TransactionEventListener方式,能够实现在控制事务同时,完成对对事件处理。..., ​   // 指定目标方法事务rollback之后执行   AFTER_ROLLBACK, ​   // 指定目标方法事务完成执行,这里完成是指无论事务是成功提交还是事务回滚了  ...给出一下结论,@EventListener标注方法是加入在当前事务执行逻辑里面的,主方法事务一体。

1K30

谈谈SpringBoot 事件机制

要“监听”事件,我们总是可以将“监听器”作为事件源中另一个方法写入事件,但这将使事件监听器逻辑紧密耦合。 对于实际事件,我们比直接方法调用更灵活。...---- 为什么应该使用事件而不是直接方法调用? 事件直接方法调用都适合于不同情况。使用方法调用,就像断言一样-无论发送和接收模块状态如何,他们都需要知道此事件发生。...当Spring路由一个事件,它使用侦听器签名来确定它是否事件匹配。 异步事件侦听器 默认情况下,spring事件是同步,这意味着发布者线程将阻塞,直到所有侦听器都完成对事件处理为止。...我们可以将侦听器绑定到事务以下阶段: AFTER_COMMIT:事务成功提交后,将处理该事件。如果事件侦听器仅在当前事务成功才运行,则可以使用此方法。...AFTER_COMPLETION:事务提交或回滚将处理该事件。例如,我们可以使用它在事务完成后执行清理。 AFTER_ROLLBACK:事务回滚后将处理该事件

2.5K30
  • 掌握 Spring事件处理

    通常做法就是方法里直接使用订单服务更新数据, 然而这样实现上两个模块出现了紧密耦合,如果订单更新操作需要进行调整,那么支付回代码块中也需要被修改。...为了避免这样情况发生,采用了 Spring 事件发布订阅方式来实现接受支付回,发布通知更新订单状态这个功能,让订单服务更新数据操作只依赖特定事件,而不用关心具体触发对象,也能达到代码复用目的...,内置标准事件有 5 种: 当 Spring 容器处于初始化或者刷新阶段就会触发,事实是ApplicationContext#refresh()方法用时,此时容器已经初始化完毕。...为什么说这个注解方式侦听事件更加灵活呢,我们可以先看下 @EventListener 注解源码。...而这样采用单线程同步方式处理好处主要是可以保证让事件处理发布者处于同一个事务环境里,如果多个侦听方法涉及到数据库操作保证了事务存在。

    1.2K40

    Spring事务监听机制---使用@TransactionalEventListener处理数据库事务提交成功后再执行操作(附:Spring4.2新特性讲解)【享学Spring

    @TransactionalEventListener 首先不得不说,从命名中就可以直接看出,它就是个EventListener Spring4.2+,有一种叫做@TransactionEventListener...方式,能够 控制 事务时候Event事件处理方式。...~~~ applicationEventPublisher.publishEvent(new MyAfterTransactionEvent("是和事务相关事件,请事务提交后执行~...是1 它肯定是在上面事务提交之后才会执行 log.info(source + ":" + count.toString()); //是和事务相关事件,请事务提交后执行~...以上,建立小伙伴已经知晓了Spring事件/监听机制基础上,回头看Spring事务监听机制其实就非常非常简单了(没有多少新东西)。

    12.1K102

    Spring学习笔记(10)一spring容器事件ApplicationEvent使用

    使用Spring作为前端MVC控制器,当Spring处理用户请求结束后,系统会自动触发该事件 2) 方法2:@EventListener 注解和 1、)使用@EventListener 注解,实现对任意方法都能监听事件...查询不到刚才入库数据,这是因为事务还没提交完成,同一个事务当中,查询不到才存入数据,那么就引出了下面的解决方式。...(2) 事务同步管理器TransactionSynchronizationManager。 以便我们可以事务提交后再触发某一事件来进行其他操作。...@TransactionalEventListener详解,从命名上直接看出,它就是个EventListenerSpring4.2+,通过@TransactionEventListener方式...而@TransactionEventListener仍是通过这种方式,但是加入了回方式来解决,这样就能够事务进行Commited,Rollback…等时候才去进行Event处理,来达到事务同步目的

    1.1K20

    深入理解Spring事件机制(二):事件推送

    大家好,又见面了,是你们朋友全栈君。 前言 Spring 从 3.x 开始支持事件机制。...开始前,推荐先阅读前文了解一点 Spring 注解机制或者事务机制,这将更有利于流程一些代码理解。...相关文章: 深入理解Spring事件机制(一):广播器监听器初始化 深入理解Spring事件机制(二):事件推送 一、事件推送 1、将事件推送到上下文 当我们借助 Spring 发送一个事件对象时候...对应回方法; TransactionSynchronizationEventAdapter 方法中,再确认当前事务阶段 @TransactionalEventListener 中 phase...若广播器中注册了线程池,则会直接把操作提交到线程池中执行; 若广播器中没有注册线程,则会直接在当前线程执行; 监听器调用时候,处理基本内事件处理,而注解监听器还额外支持一些功能,比如:

    1.8K20

    从注解@EventListener和@TransactionalEventListener掌握Spring事件机制原理 - Java技术债务

    当一个事件带有@TransactionalEventListener注解监听器方法处理,它将在一个事务上下文中被调用。...这意味着事件处理过程中发生任何数据库变化将根据Spring应用程序事务性设置提交或回滚。...我们可以从命名上直接看出,它就是个 EventListenerSpring4.2+,有一种叫做 @TransactionEventListener方式,能够实现在控制事务同时,完成对事件处理。...TransactionSynchronization 接口只是抽象了一些行为,用于事务事件发生触发,这些行为Spring事务中提供了内在支持,即在相应事务事件,其会获取当前所有注册 TransactionSynchronization...TransactionalApplicationListenerMethodAdapter 本质上是实现了 ApplicationListener 接口,也就是说,其是Spring一个事件监听器,这也就是为什么进行事务处理需要使用

    44710

    Spring原理剖析

    ,从而导致第一个事务更新数据丢失,这是由于没有加锁造成 脏读 一个事务看到了另一个事务提交更新数据 不可重复读、 同一事务中,多次读取同一数据却返回不同结果;也就是有其他事务更改了这些数据...不可重复读重点是修改 幻读 一个事务执行过程中读取到了另一个事务提交插入数据;即在第一个事务开始读取到一批数据,但此后另一个事务又插入了新数据并提交,此时第一个事务又读取这批数据但发现多了一条...这些方法都集中定义事件监听者(EventListener)接口中。...Stop()方法停止容器触发该事件 RequestHandleEvent: Web应用中,当一个http请求(request)结束触发该事件 跟观察者模式区别 模型结构不同 EventListener...记得好像VB或C#也是这种模型 Observer模式模型就简洁多了,没有分事件源和事件,二者合二为一为一个角色:观察者,从字面语义上也应该这样,另一个是观察者角色 就是上面说Observer模式比较

    70610

    spring事件监听应用场景_java监听器原理实现

    大家好,又见面了,是你们朋友全栈君。 前言 Spring 从 3.x 开始支持事件机制。...笔者将基于 Spring 源码 5.2.x 分支,分析该功能是如何实现。 本文是其中第一篇文章,将分析广播器监听是如何初始化,并完成注解流程。...开始前,推荐先阅读前文了解 Spring 容器初始化过程 BeanFactory 中 Bean 创建,如果可能,还可以了解一点 Spring 注解机制,这将更有利于流程一些代码理解。...相关文章: 深入理解Spring事件机制(一):广播器监听器初始化 深入理解Spring事件机制(二):事件推送 一、广播器创建 在前文,我们知道容器初始化是通过 AbstractApplicationContext.refresh...而这个抽象方法不同上下文会有不同实现,但是基本都要通过不同 BeanDefinitionReader 去完成这个过程。

    89310

    Spring事件机制实践

    新建一个事件监听器,注入到Spring容器中,交给Spring管理。指定方法上添加@EventListener参数为监听事件。方法为业务代码。...用户userId为:" + event.getUserId()); } } @TransactionalEventListener来定义一个监听器,他@EventListener不同就是@EventListener...AFTER_COMMIT(指定目标方法事务commit之后执行)、 * AFTER_ROLLBACK(指定目标方法事务rollback之后执行)、AFTER_COMPLETION(指定目标方法事务完成执行...直接注入我们ApplicationEventPublisher,使用@Autowired注入一下。 三种发布事件方法,给大家演示一下@Autowired注入方式发布我们事件。...如果发布事件方法处于事务中,那么事务会在监听器方法执行完毕之后才提交事件发布之后就由监听器去处理,而不要影响原有的事务,也就是说希望事务及时提交

    1.2K01

    Spring 事件驱动模型

    spring4.2 以后可以以更加简洁方式来监听 event 发布,监听事件不必再实现 ApplicationListener 接口了,只要在方法上添加注解 @EventListener即可。...一个事件可以同时多个监听处理类监听处理。 默认情况下事件是同步,即事件 publish 后会等待 Listener 处理。如果发布事件业务存在事务,监听器处理也会在相同事务中。...注:启动类上同时要加上@EnableAsync 利用@TransactionalEventListener实现监听事件事务隔离 很多时候,只有事务提交之后才会发布相应事件处理其他逻辑,比如用户注册之后...):事务提交前 @TransactionalEventListener 指不和发布事件方法同一个事务内,发布事件方法事务结束后才会执行本监听方法,监听逻辑内发生异常不会回滚发布事件方法事务。...fallbackExecution=true,则指发布事件方法没有事务控制,监听方法仍可以监听事件进行处理。

    1.5K20

    Spring事务专题(五)聊聊Spring事务到底是如何实现

    ,这个类本身就是一个事件监听器,当容器中组件发布了一个事件后,如果事件匹配,会进入它onApplicationEvent方法,这个方法并没有直接执行我们所定义监听逻辑,而是给当前事务注册了一个同步行为...同时初始化了同步事务过程中要执行一些回(也就是一些同步行为) 在前面我们已经介绍了直接调用」情况下,如果传播级别为mandatory会直接抛出异常,传播级别为required、requires_new...嵌套调用流程 前面已经介绍了直接调用下七种不同隔离级别在创建事务不同表现,代码看似很多,实际还是比较简单,接下来我们要介绍就是嵌套调用,也就是已经存在事务情况下,调用了另外一个事务管理方法...这个事务回滚,只会回滚到指定保存点。同时因为它跟外围事务共用一个连接,所以它会跟随外围事务提交提交,回滚而回滚。...到目前为止,我们就介绍完了事务创建,紧接着就是真正执行业务代码了,要保证业务代码能事务管理,最重要一点是保证在业务代码中执行SQL仍然是使用我们开启事务绑定到线程上数据库连接。

    1.3K10

    分析Spring是如何做事务事件监控

    无论是事务开始,提交或者回滚,都会触发相应事务事件。本文首先会使用实例进行讲解Spring事务事件是如何使用,然后会讲解这种使用方式实现原理。...// 指定目标方法事务完成执行,这里完成是指无论事务是成功提交还是事务回滚了 AFTER_COMPLETION } 这里我们假设数据库有一个user表,对应有一个UserService...接口只是抽象了一些行为,用于事务事件发生触发,这些行为Spring事务中提供了内在支持,即在相应事务事件,其会获取当前所有注册TransactionSynchronization对象,然后调用其相应方法...ApplicationListenerMethodTransactionalAdapter本质上是实现了ApplicationListener接口,也就是说,其是Spring一个事件监听器,这也就是为什么进行事务处理需要使用...Spring事务监听器使用过程中,需要注意是要对当前接收到事件类型进行判断,因为不同事务可能会发布同样消息对象过来。

    79920

    Spring高手之路7——事件机制监听器全面探索

    Spring观察者模式   观察者模式是一种行为设计模式,它定义了对象之间依赖关系,当一个对象状态发生改变,所有依赖于它对象都会得到通知并自动更新。...Spring中,事件模型工作方式也是类似的: 当Spring应用程序中发生某个行为时(比如一个用户完成了注册),那么产生这个行为组件(比如用户服务)就会创建一个事件,并将它发布出去。...Spring提供了@EventListener注解,我们可以在任何一个方法上使用这个注解来指定这个方法应该在收到某种事件调用。   ...; } } 运行结果: ContextClosedEvent事件Spring应用上下文关闭发布,这通常在所有的单例Bean已经销毁之后。...这意味着事件触发,我们可以通过事件对象直接获取到发生事件应用上下文,而不需要进行额外操作。

    1.4K40

    Spring认证中国教育管理中心-Apache Geode Spring 数据教程十九

    使用事务,可能需要注册一个侦听器,以便在事务提交之前或之后或发生回滚之后执行某些操作。...Spring Data for Apache Geode 使创建侦听器变得容易,这些侦听器将在具有@ TransactionalEventListener注释事务特定阶段调用 。...带注释方法@TransactionalEventListener(如下所示)将在指定通知从事务方法发布事件,phase。...但是,如果您仍然希望提交之前”接收事务事件,那么您仍然必须 applicationEventPublisher.publishEvent(..)应用程序@Transactional @Service...简而言之,CQ 允许开发人员创建和注册 OQL 查询,然后添加到 Apache Geode 新数据查询谓词匹配自动收到通知。

    94010

    简单高效代码优化-事务后异步处理

    EventListener,你可以很快速迁移知识到Spring @TransactionalEventListener 帮助解耦代码,实现事务提交后异步执行分支流程,@TransactionalEventListener...Spring中我们可以很方便使用TransactionSynchronizationManager.registerSynchronization执行事务方法,并实现TransactionSynchronizationAdapter...)构建依赖于上文事务结果,你才需要使用该方法,否则直接采用applicationEventPublisher.pushEvent即可,register只是提供了除注解外手动事务实现,用于更细微代码控制...签收分支流程分为如下几个大类,重构可按照不同类型分类监听 tip: 由于监听者是异步线程,所以监听者内部抛出异常是不能够全局异常捕获,我们可以像上文insertItemOpen方法一样,catch...住异常再选择是抛出还是打印日志 不同于EventBus,idea中,天然支持了Spring Event跟踪,点击事件发布者左侧绿标,便可以找到对应事件监听者 点击监听者旁绿标同样可以回到事件发布者

    49450

    Spring框架 SpringEvent

    Spring事件(Application Event)其实就是一个观察者设计模式,一个 Bean 处理完成任务后希望通知其它 Bean 或者说 一个Bean 想观察监听另一个Bean行为。...一个事件可以同时多个监听处理类监听处理。 如果代码结构较复杂,多处发布相同事件,建议发布事件将this作为source传递,便于通过分析日志确定发布源。...如果要监听多个事件类型发布,可以@EventListener(classes = {FaceEvent.class,ArmEvent.class})指定,spring会多次调用此方法来处理多个事件。...如果有多个监听器监听同一事件,我们可以方法上使用spring@order注解来定义多个监听器顺序,如: @EventListener @Order(4) public void onApplicationEvent...扩展 - 监听事件事务隔离 ​ @TransactionalEventListener和@EventListener都可以监听事件,但前者可以对发布事件和监听事件进行一些事务隔离。 ​

    23220

    【小家Spring】从Spring(ApplicationEvent)事件驱动机制出发,聊聊【观察者模式】【监听者模式】【发布订阅模式】【消息队列MQ】【EventSourcing】...

    相当于事件监听者(监听器),观察者(Observable)相当于事件源和事件,执行逻辑通知observer即可触发oberverupdate,同时可传观察者和参数。...所有事件监听器都需要实现该接口。事件监听器注册事件源上,当事件属性或状态改变时候,调用相应监听器内方法(自己写)。 Source:一个普通POJO。...使用Spring作为前端MVC控制器,当Spring处理用户请求结束后,系统会自动触发该事件(即ServletRequestHandledEvent) ApplicationContextEvent...是一个非常经典行为型设计模式。。猫叫了,主人醒了,老鼠跑了,这一经典例子,是事件驱动模型设计层面的体现。 发布订阅模式:很多人认为等同于观察者模式。...Spring一些简单事件驱动机制,相信如果之后再看到Event,Publisher,EventListener·一类单词后缀,也能立刻和事件机制联系上了

    6.8K71

    Spring源码】Spring Event事件

    今天就来讲一下Spring事件机制。 2、什么是Spring Event? Spring框架中事件是一种观察者设计模式实现,用于应用程序中处理各种状态变化。...事件驱动编程是一种流行编程范式,其中组件之间通信是通过事件(或消息)进行Spring事件机制允许对象状态发生变化时发布事件,其他对象则可以订阅这些事件并在事件发生执行特定操作。...* condition声明只有事件code==200,才进入该事件 */ @EventListener(classes = {DamIllegalDataEvent.class},...5、@TransactionalEventListener 提到事件,这里再提一个注解@TransactionalEventListener,也即感知事务,基于事件形式事务某个阶段进行绑定。...比如在事务提交之前或之后进行一些业务处理,如短信提醒等等。@TransactionEventListener允许事件处理方法感知事务。它phase属性,表示希望事务哪个阶段执行事件处理。

    32110

    简单高效代码优化-事务后异步处理

    EventListener,你可以很快速迁移知识到Spring @TransactionalEventListener 帮助解耦代码,实现事务提交后异步执行分支流程,@TransactionalEventListener...Spring中我们可以很方便使用TransactionSynchronizationManager.registerSynchronization执行事务方法,并实现TransactionSynchronizationAdapter...事件实体(本文OrderSignEvent)构建依赖于上文事务结果,你才需要使用该方法,否则直接采用applicationEventPublisher.pushEvent即可,register只是提供了除注解外手动事务实现...签收分支流程分为如下几个大类,重构可按照不同类型分类监听 tip: 由于监听者是异步线程,所以监听者内部抛出异常是不能够全局异常捕获,我们可以像上文insertItemOpen方法一样,catch...住异常再选择是抛出还是打印日志 不同于EventBus,idea中,天然支持了Spring Event跟踪,点击事件发布者左侧绿标,便可以找到对应事件监听者 点击监听者旁绿标同样可以回到事件发布者

    88521
    领券