文档章节

Spring Event 事件中的事务控制

刘少
 刘少
发布于 2017/04/20 17:11
字数 566
阅读 715
收藏 0

Spring Event 可以简单实现业务解耦,从Spring 4.2以后,事件处理不用实现ApplicationListener 的 onApplicationEvent方法了,使用注解@EventListener可以自动关联相关的ApplicationListener

    @EventListener(condition = "#event.shouldSendMsg")
    public void afterRegisterSendMail(MessageEvent event) {
         mailService.send(event.getUser().getEmail(),"register successful");
    }

事务绑定事件

标准的事件模型在一些业务上能很好的满足需求,例如异步化处理,不干扰主线程执行等,不论事务被提交或回滚,都能正常执行.但是如果我们只是希望事务被提交后,再执行事件呢?

例如,用户注册成功后添加一个发送邮件的事件,或者推送消息,或者短信,这时候需要保存数据库后,再进行这些操作.但是万一事务提交失败数据库事务会回滚,这时候如果用户收到邮件,那可惨淡了!

在Spring事务管理中, 事务是配置注解声明的 (@Transactional) 提交操作将在方法结束后执行. 提交是自动自行的(transaction.commit()). 以下是一些解决方式:

解决方案1(<Spring 4.2):

@EventListener
public void afterRegisterSendMail(MessageEvent event) {
    // Spring 4.2 之前
 
    TransactionSynchronizationManager.registerSynchronization(
            new TransactionSynchronizationAdapter() {
                @Override
                public void afterCommit() {
                    internalSendMailNotification(event);
                }
            });
}

上面的代码将在事务提交后执行.如果在非事务context中将抛出java.lang.IllegalStateException: Transaction synchronization is not active,

	@EventListener
		public void afterRegisterSendMail(MessageEvent event) {
		    // Spring 4.2 之前
		 
		    if (TransactionSynchronizationManager.isActualTransactionActive()) {
		 
		        TransactionSynchronizationManager.registerSynchronization(
		                new TransactionSynchronizationAdapter() {
		                    @Override
		                    public void afterCommit() {
		                    	mailService.send(event);
		                    }
		                });
		    } else {
		        mailService.send(event);
		    }
		}

这样无论是否有事务都能兼容啦. 下面介绍Spring 4.2以后的简化处理:

解决方案2(Spring 4.2 +)

Spring 4.2除了EventListener之外,额外提供了新的注解TransactionalEventListener

	    @TransactionalEventListener
		public void afterRegisterSendMail(MessageEvent event) {
			mailService.send(event);
		}

这个注解的强大之处在于可一直控制事务的 before/after commit, after rollback ,after completion (commit或 rollback). 默认情况下,在事务中的Event将会被执行,其他情况不触发.

在非事务context下,如果也想执行,启用参数:fallbackExecution=true,

	    @TransactionalEventListener(fallbackExecution = true)
		public void afterRegisterSendMail(MessageEvent event) {
			mailService.send(event);
		}

 

https://my.oschina.net/osgit/blog/883823

© 著作权归作者所有

共有 人打赏支持
刘少
粉丝 12
博文 31
码字总数 12465
作品 0
海淀
程序员
私信 提问
SpringBoot | 第三十二章:事件的发布和监听

前言 今天去官网查看资料时,在特性中看见了章节。想想,的事件应该是在版本就发布的功能了,并越来越完善,其为和之间的消息通信提供了支持。比如,我们可以在用户注册成功后,发送一份注册...

oKong
2018/11/06
0
0
用Spring Cloud Stream实现Event Driven Architectures

微服务的出现和原生的云架构触发了DDD,CQRS和Event Sourcing的复苏。所有这些方式实现的核心是Domain Event(领域事件), 它是分布式系统中实现一整套DDD架构及实现最终一致性的主要机制。...

Big_BoBo
2017/10/19
0
0
Spring5源码解析-Spring框架中的事件和监听器

事件和平时所用的回调思想在与GUI(JavaScript,Swing)相关的技术中非常流行。而在Web应用程序的服务器端,我们很少去直接使用。但这并不意味着我们无法在服务端去实现一个面向事件的体系结构...

Java小铺
2018/08/10
0
0
Java框架 Spring 核心机制

概念 轻量级的(面向切面AOP)、(IOC控制反转)容器框架。 Spring优点 1.降低组件之间的耦合性 2.专注于自己业务逻辑,统一的行为(日志、安全等)抽象出来统一处理 3.易于单元测试 4.方...

java知识分子
2018/09/28
0
0
Hasor JDBC 的难关,嵌套事务处理思路

本文存属提醒我自己不要忘记的事情。也是向大家展示 Hasor 对于 JDBC 方面即将的又一个重大的进步。目前该方案还在实施中。 前段时间闲着没事分析了下 Spring JDBC ,觉得 Spring JDBC 的设计...

哈库纳
2013/12/29
0
9

没有更多内容

加载失败,请刷新页面

加载更多

外教比较

确定收费的模式 确定授课的模式 确定教学的方式-用什么样的方式能让人更快更好的学会 确定核心竞争力-比如我们的师资是牛津大学的 英语流利说 收费的模式-报特色课程,比如训练营之类的,其实...

V字仇杀
17分钟前
1
0
上下文无关文法介绍

上下文无关文法 上下文无关文法是用来描述程序语言的一种表达方式,通过简单的符号描述语言的集合。正如我们所知道,一个程序即为一个句子(字符串),语言就是所有句子的集合。上下文无关文...

陶小陶
26分钟前
3
0
eggjs与sequelize简单demo

参考 egg 官方文档 安装 // 依赖npm install --save egg-sequelize mysql2// ts 类型npm install --save @types/sequelize 插件,config/plugin.ts import { EggPlugin } from 'egg';......

Geeyu
今天
1
0
看过上百部片子的这个人教你视频标签算法解析

本文由云+社区发表 随着内容时代的来临,多媒体信息,特别是视频信息的分析和理解需求,如图像分类、图像打标签、视频处理等等,变得越发迫切。目前图像分类已经发展了多年,在一定条件下已经...

腾讯云加社区
今天
4
0
2. 红黑树

定义:红黑树(Red-Black Tree,简称R-B Tree),它一种特殊的二叉查找树(Binary Search Tree)。 要理解红黑树,先要了解什么是二叉查找树。在上一章中,我们学习了什么是二叉树,以及二叉树...

火拳-艾斯
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部