在Spring 4.2中更简单地处理异步事务绑定事件

介绍

如您可能已经知道的(例如,从我以前的博客文章中 ),不再需要创建一个单独的类,该类使用onApplicationEvent方法实现ApplicationListener以便能够对应用程序事件做出响应(包括来自Spring Framework本身和我们自己的域事件)。 从Spring 4.2开始,添加了对注释驱动的事件侦听器的支持。 在方法级别使用@EventListener就足够了,该方法级别将在@EventListener自动注册相应的ApplicationListener

@EventListenerpublic void blogAdded(BlogAddedEvent blogAddedEvent) {externalNotificationSender.blogAdded(blogAddedEvent);}

请注意 ,在事件中使用域对象有明显的缺点,在许多情况下也不是最好的主意。 代码示例中的伪域对象用于不引入不必要的复杂性。

交易绑定事件

简单紧凑。 对于“标准”事件,一切看起来都很不错,但在某些情况下,需要在事务提交(或回滚)之后执行一些操作(通常是异步操作)。 那是什么 是否可以使用新机制?

业务需求

首先,是一个小题外话-业务需求。 让我们想象一下超级精美的博客聚合服务。 每次添加新博客时都会生成一个事件。 订阅的用户可以接收SMS或推送通知。 可以在将博客对象计划保存在数据库中之后发布该事件。 但是,在提交/刷新失败(违反数据库约束,ID生成器出现问题等)的情况下,整个数据库事务都会回滚。 通知破损的愤怒用户会出现在门口……

技术问题

在现代的事务管理方法中,事务是声明式配置的(例如,使用@Transactional批注),并且在事务作用域的结尾(例如,方法的结尾)触发提交。 总的来说,这非常方便,而且出错的可能性要小得多(与编程方法相比)。 另一方面,提交(或回滚)是在代码外自动完成的,因此我们无法以“经典方式”做出反应(即在调用transaction.commit()之后的下一行中的发布事件)。

老学校实施

不可或缺的Tomek Nurkiewicz提出了Spring的一种可能的解决方案(也是一种非常优雅的解决方案)。 它使用TransactionSynchronizationManager来注册当前线程的事务同步。 例如:

@EventListenerpublic void blogAddedTransactionalOldSchool(BlogAddedEvent blogAddedEvent) {//Note: *Old school* transaction handling before Spring 4.2 - broken in not transactional contextTransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {@Overridepublic void afterCommit() {internalSendBlogAddedNotification(blogAddedEvent);}});}

所传递的代码在Spring事务工作流中的适当位置执行(对于这种情况,“恰好”在提交后执行)。

为了提供对非事务上下文中执行的支持(例如,在不关心事务的集成测试用例中),可以将其扩展为以下形式,以确保不会因java.lang.IllegalStateException: Transaction synchronization is not active而失败java.lang.IllegalStateException: Transaction synchronization is not active异常:

@EventListenerpublic void blogAddedTransactionalOldSchool(final BlogAddedEvent blogAddedEvent) {//Note: *Old school* transaction handling before Spring 4.2//"if" to not fail with "java.lang.IllegalStateException: Transaction synchronization is not active"if (TransactionSynchronizationManager.isActualTransactionActive()) {TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {@Overridepublic void afterCommit() {internalSendBlogAddedNotification(blogAddedEvent);}});} else {log.warn("No active transaction found. Sending notification immediately.");externalNotificationSender.newBlogTransactionalOldSchool(blogAddedEvent);}}

在缺少活动交易的情况下,通过进行此更改,可以立即执行提供的代码。 到目前为止,一切正常,但是让我们尝试在Spring 4.2中使用注释驱动的事件侦听器实现相同的目的。

Spring 4.2+实施

除了@EventListener之外,Spring 4.2还提供了另一个注解@TransactionalEventListener

@TransactionalEventListenerpublic void blogAddedTransactional(BlogAddedEvent blogAddedEvent) {externalNotificationSender.newBlogTransactional(blogAddedEvent);}

执行可以绑定到标准事务阶段:提交之前/之后,回滚之后或完成之后(提交或回滚)。 默认情况下,只有在事件的边界内发布事件时,它才会处理事件。 在其他情况下,该事件将被丢弃。

为了支持在非事务上下文中的执行,可以使用falbackExecution标志。 如果设置为“ true”,则如果没有事务在运行,则将立即处理事件。

@TransactionalEventListener(fallbackExecution = true)public void blogAddedTransactional(BlogAddedEvent blogAddedEvent) {externalNotificationSender.newBlogTransactional(blogAddedEvent);}

摘要

在Spring 4.2中引入的注释驱动的事件侦听器延续了减少基于Spring(Boot)的应用程序中样板代码的趋势。 无需手动创建ApplicationListener实现,无需直接使用TransactionSynchronizationManager只需一个具有正确配置的注释即可。 硬币的另一面是,找到所有事件侦听器会有些困难,尤其是在我们的整体应用程序中有数十个事件侦听器的情况下(尽管可以很容易地对其进行分组)。 当然,新方法仅是一种选择,它在给定的用例中是否有用。 尽管如此,Spring(Boot)的另一个魔力泛滥到了我们的系统中。 但是也许抵抗是徒劳的?

抵抗是徒劳的吗?资料来源:http://en.memory-alpha.wikia.com/wiki/Borg_cube

抵抗是徒劳的吗?
资料来源: http : //en.memory-alpha.wikia.com/wiki/Borg_cube

请注意,Spring Framework 4.2是Spring Boot 1.3的默认依赖项(在编写1.3.0.M5时可用)。 另外,可以在Gradle / Maven中为Spring Boot 1.2.5手动升级Spring Framework版本–在大多数情况下它应该可以使用。

  • 可以从GitHub获得代码示例。

顺便说一句,为该博客文章编写示例使我有了使用Spring 4.1中引入的新测试事务管理系统的第一种真正能力(过去,我仅在Spring培训课程中提到过)。 可能,我会尽快写更多有关它的内容。

翻译自: https://www.javacodegeeks.com/2015/10/simpler-handling-of-asynchronous-transaction-bound-events-in-spring-4-2.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/356699.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux chattr 无权限,从零开始学习Linux(二十八):文件权限之chattr权限

1、chattr命令命令格式: chattr [-] [选项] 文件名或者目录名;参数说明::增加权限;-:删除权限; 等于某权限;选项说明:i:如果对文件设置i属性,则不…

初等数论及其应用——中国剩余定理

在线性代数中,我们用高斯消元解决多元的线性方程组,而在数论中,面对一元变量的线性模方程组,我们利用中国剩余定理去求解x。 转载于:https://www.cnblogs.com/rhythmic/p/5928483.html

linux下编译openjdk7,Ubuntu 14.04.3 64位环境下OpenJDK7编译

系统环境:Ubuntu 14.04.3 -amd64 in VMWare1.安装openjdk7依赖sudo apt-get build-dep openjdk-7sudo apt-get install openjdk-7-jdksudo apt-get install build-essential gawk m4 libasound2-dev libcups2-dev libxrender-dev xorg-dev xutils-dev x11proto-prin…

jQuery选择器的效率问题

jQuery提供了功能强大,并兼容多种css版本的选择器,不过发现很多同学在使用选择器时并未注重效率的问题。 a) 尽量使用Id选择器,jQuery选择器使用的API都是基于getElementById或getElementsByTagName,因此可以知道效率最高的是Id选…

HTTP请求和标头参数的CDI拦截器-简单示例

在使用Java EE开发和发展REST API的过程中,有些情况下您希望以更细粒度的方式(视情况而定)对传入的HTTP请求(特别是标头参数)进行“观察” Servlet过滤器或更具体的ContainerRequestFilters 。 我发现在某些情况下非常…

csgo服务器搭建 linux,请问搭建csgo服务器切换创意工坊地图报错怎么办

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼Unknown command "sv_maxcmdrate"Unknown command "cash_team_elimination_hostage_map"Unknown command "cash_team_win_by_time_running_out"Unknown command "sv_vote_creation_time"W…

1405 树的距离之和

1405 树的距离之和 基准时间限制&#xff1a;1 秒 空间限制&#xff1a;131072 KB给定一棵无根树&#xff0c;假设它有n个节点&#xff0c;节点编号从1到n, 求任意两点之间的距离&#xff08;最短路径&#xff09;之和。Input第一行包含一个正整数n (n < 100000)&#xff0c…

linux c 11 运行库,11.1.3 运行库与I/O

11.1.3 运行库与I/O在了解了glibc和MSVC的入口函数的基本思路之后&#xff0c;让我们来深入了解各个初始化部分的具体实现。但在具体了解初始化之前&#xff0c;我们要先了解一个重要的概念&#xff1a;I/O。IO(或I/O)的全称是Input/Output&#xff0c;即输入和输出。对于计算…

设置Elasticsearch N-Gram Word分析器的过程

说n-gram是一个大话题&#xff0c;这是轻描淡写的。 进行快速搜索&#xff0c;您会发现自己盯着语言学和语言模型&#xff0c;数据挖掘或特定蛋白质的分解对首次亮相文化的衰落所隐含的信息量。 好吧&#xff0c;我在跟那最后一个开玩笑。 但是&#xff0c;如果您是开发人员&a…

linux windows 丢失,Win10预览版9879硬盘丢失的Linux解决方案

IT之家讯 12月3日消息&#xff0c;最近IT之家论坛网友九仙仙总结了Win10预览版9879硬盘问题的解决方法&#xff0c;并在论坛中发布出来。经测试&#xff0c;此为快速有效的解决方法&#xff0c;故公之于众供朋友们参考。以下为作者原文。开头说明两点&#xff1a;1、这是我个人…

linux单网卡多拨Adsl,ROS单线多拨pppoe

#设置内网IP地址/ ip add add interfaceether1address192.168.0.254/255.255.255.0#设置共享上网/ ip firewall nat add actionmasquerade chainsrcnatsrc-address192.168.0.0/255.255.255.0#设置ADSL拔号/ interface pppoe-client add name"pppoe-out1" interfaceet…

Android开发——Android系统启动以及APK安装、启动过程

0. 前言 从Android手机打开开关&#xff0c;到我们可以使用其中的app时&#xff0c;这个启动过程到底是怎么样的&#xff1f;1. 系统上电当给Android系统上电&#xff0c;在电源接通的瞬间&#xff0c;CPU内的寄存器和各引脚均会被置为初始状态&#xff0c;CPU复位之后&#…

linux生成文件清单,Linux 获取文件名称生成列表 txt - create_filelist

Linux 获取文件名称生成列表 txt - create_filelist1. find/home/strong/MOTChallenge/MOT16/MOT16/train/MOT16-04/img1/ 文件夹下所有 *.jpg (000001.jpg - 001050.jpg) 的路径 图片名信息写入 txt 文件。1.1 llstrongforeverstrong:~/MOTChallenge/MOT16/MOT16/train/MOT16…

jvm线程分析命令_JVM:如何分析线程转储

jvm线程分析命令本文将教您如何分析JVM线程转储&#xff0c;并查明问题的根本原因。 以我的观点&#xff0c;线程转储分析是掌握Java EE生产支持的任何个人最重要的技能。 您可以从线程转储快照中获取的信息量通常远远超出您的想象。 我的目标是与您分享我在过去10年中积累的有…

[na]华为acl(traffic-filter)和dhcp管理

这个是财务网络的一个问题, 要求财务的某台机器能访问其他部门区的打印机. 其他部门是不能访问到财务网络的. 华为alc配置实例:-traffic-filter # 在VLAN100上配置基于ACL的报文过滤&#xff0c;允许源IP地址为192.168.0.2/32的报文通过&#xff0c;丢弃其他报文。 <HUAWEI&…

svn 1.6 linux 下载,LINUX下Subversion1.6.17 部署

1、服务器版本和安装软件服务器版本&#xff1a;Redhat Enterprise 5.5 32bit安装软件&#xff1a;apr-1.3.12.tar.gzapr-util-1.3.12.tar.gzhttpd-2.2.9.tar.gzsqlite-amalgamation-3.7.3.tarsubversion-1.6.17.tar.bz2subversion-deps-1.6.17.tar.bz22、安装检查操作系统http…

JBoss Fuse –使用MVEL将您的静态配置转换为动态模板

最近&#xff0c;我重新发现了我遗忘的JBoss Fuse功能&#xff0c;并且我认为其他人可能会从此提醒中受益 。 这篇文章将重点放在JBoss Fuse和Fabric8上&#xff0c;但所有正在寻找最小侵入性方法来为其静态配置文件添加一定程度的动态支持的开发人员也可能会对此感兴趣。 在…

在linux中dns不安装coching,ubuntu 8.04下openldap的安装和使用

ubuntu 8.04上openldap的安装和使用1、安装openldap。$ sudo apt-get install slapd ldap-utils2、配置openldap。$ sudo /etc/ldap/slapd.conf需要修改的有以下4处。# The base of your directory in database #1# 域名前缀suffix "dcpeercoaching,dccn"# …

linux 拿shell,linux下备份拿shell[渗透必备]

关于php包含Apache日志的利用,其实也就是利用提交的网址里有php语句&#xff0c;然后再被Apache服务器的日志记录&#xff0c;然后php再去包含执行&#xff0c;从而包含了去执行。当然&#xff0c;这种办法最大的弊端是Apache日志肯定会过大&#xff0c;回应的时候当然会超时什…

信息系统开发内容

1.按照用于质量管理的能力成熟度模型&#xff08;CMM&#xff09;描述系统开发过程的动机。 2.区分系统生命周期和系统开发方法 3.描述系统开发的10个基本原理 4.定义问题、机会和指示——系统开发项目的能力 5.描述用于把问题、机会和指示进行分类的PIECES框架 6.描述系统开发…