Spring中的事务提交事件

news/2024/10/18 16:53:26

如果想在spring操作事务结束后执行一些代码,应该怎么办?

为什么要这样?比如我们在事务中给其他系统发了消息,期望事务提交后过一会收到这个系统的回应,然后操作刚刚提交的数据。但是如果回应来的太快就像龙卷风,我们的事务是托管给Spring的可能还没提交,也就没法操作了

一个方案是使用 ApplicationEventPublisher,可以参考我之前的千万访问量博客
https://www.iteye.com/blog/somefuture-2405963

登陆访问量是100多万,我就假设总访问量是10倍吧哈哈
image

这个API是 Spring 1 就提供的,从 Spring 5 开始,提供了一个新的事物相关的API,叫 TransactionSynchronization 事物同步机制。

上代码

先编写一个Bean实TransactionSynchronization接口

import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.stereotype.Component;@Component
public class AfterTransactionCommitExecutor implements TransactionSynchronization {@Overridepublic void afterCommit() {// 事务提交后执行的操作System.out.println("事务已提交,执行后续操作");}// 其他需要重写的方法...public void registerSynchronization() {// 注册当前实例到事务同步管理器TransactionSynchronizationManager.registerSynchronization(this);}
}

然后,你可以在服务层或者合适的地方调用registerSynchronization()方法来注册事务同步回调

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class SomeService {@Autowiredprivate AfterTransactionCommitExecutor afterTransactionCommitExecutor;@Transactionalpublic void doWork() {// 业务逻辑...// 注册事务同步回调afterTransactionCommitExecutor.registerSynchronization();}
}

基本上使用它还是为了操作数据,所以需要把参数传给他。

一 成员变量

最简单的就是加一个成员属性。

@Component
public class AfterTransactionCommitExecutor extends TransactionSynchronizationAdapter {private Object parameter;@Overridepublic void afterCommit() {// 事务提交后使用参数执行操作doSomethingWithParameter(parameter);}public void setParameter(Object parameter) {this.parameter = parameter;}private void doSomethingWithParameter(Object parameter) {}public void registerSynchronization() {TransactionSynchronizationManager.registerSynchronization(this);}
}
@Service
public class SomeService {@Autowiredprivate AfterTransactionCommitExecutor afterTransactionCommitExecutor;@Transactionalpublic void doWork(Object parameter) {// 设置参数afterTransactionCommitExecutor.setParameter(parameter);// 注册事务同步回调afterTransactionCommitExecutor.registerSynchronization();}
}

二 每次创建匿名类对象

@Service
public class SomeService {@Transactionalpublic void doWork(final Object parameter) {// 业务逻辑...// 注册事务同步回调并传递参数TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {@Overridepublic void afterCommit() {doSomethingWithParameter(parameter);}});}private void doSomethingWithParameter(Object parameter) {// 使用参数执行相关操作}
}

注意,在使用成员变量传递参数时,如果多个事务并发执行,可能会存在线程安全问题。为了避免这个问题,可以使用ThreadLocal来存储参数,或者在事务方法中每次都创建一个新的TransactionSynchronization实例。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

普天同悲

谨记,谨记。世人若学我,当如堕魔道。

Denoising Diffusion Implicit Models(去噪隐式模型)

DDPM有一个很麻烦的问题,就是需要迭代很多步,十分耗时。有人提出了一些方法,比如one-step dm等等。较著名、也比较早的是DDIM。 原文:https://arxiv.org/pdf/2010.02502 参考博文:https://zhuanlan.zhihu.com/p/666552214?utm_id=0 DDIM假设 DM假设 ddim给出了一个新的扩…

20222408 2024-2025-1 《网络与系统攻防技术》实验二实验报告

1.实验内容 1.1本周学习内容 本次实验中,学习的重点是后门的实现与启动方式,学习内容还有后门的定义、原理以及可能影响,netcat、socat、MSF meterpreter软件的应用。 1.2实验内容简述使用netcat获取主机操作Shell,利用cron启动一项任务 使用socat获取主机操作Shell, 利用创…

京东APP百亿级商品与车关系数据检索实践

作者:京东零售 张强导读 本文主要讲解了京东百亿级商品车型适配数据存储结构设计以及怎样实现适配接口的高性能查询。通过京东百亿级数据缓存架构设计实践案例,简单剖析了jimdb的位图(bitmap)函数和lua脚本应用在高性能场景。希望通过本文,读者可以对缓存的内部结构知识有一…

专题(二十) cut

一、作用与介绍cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符、字段写至标准输出。 二、用法选项 用法说明 举例说明 备注-b 按字节截取 who | cut -b 3 输出每行的第三个字节-c 按字符截取,常用于中文 cut -c 2 输出每行的第二个中文字符-d 指定以什么为…

【DevExpress】(多行粘贴、块粘贴)

复制是GridControl自带的属性,主要解决的是多个单元格复制的问题,这里涉及到两个参数。 主要是粘贴的 先定义两个全局变量,在单元格点击事件的时候获取单元格的行号和列号1 //获取当前选中单元格所在的列序号2 int curntindex;3 //获取获取当前选中单元格所在的行…

Jenkins+Coverage的代码覆盖率集成实践

Jenkins+Coverage的代码覆盖率集成实践 一、工具介绍Jenkins: Jenkins是一个开源的、基于Java开发的持续集成工具,它可以帮助开发人员自动化构建、测试和部署软件项目。 Coverage: Coverage是一个Python代码覆盖率工具,用于测量代码执行过程中哪些代码行被执行到,从而评估…

C++顺序结构(3)、数据类型_____教学

一、设置域宽setw() 输出的内容所占的总宽度成为域宽,有些高级语言中称为场宽。 使用setw()前,必须包含头文件iomanip,即#include<iomanip> 头文件iomanip,用来声明一些“流操作符”,需要一定格式输入输出时,就需要用到它,比较常用的有设置域宽、设置左右对齐、设置…