基于 Spring 事务同步机制的事务后置动作收集器 Starter 实践
基于 Spring 事务同步机制的事务后置动作收集器 Starter 实践一、涉及的技术知识点1.1 Spring 事务同步机制知识点说明TransactionSynchronizationSpring 提供的事务同步回调接口在事务提交/回滚后触发TransactionSynchronizationAdapter适配器类选择性覆写需要的回调方法TransactionSynchronizationManager管理当前线程的事务同步器注册afterCommit()事务提交成功后调用afterCompletion(status)事务完成后调用无论提交还是回滚status 标识结果事务状态常量STATUS_COMMITTED0、STATUS_ROLLED_BACK1、STATUS_UNKNOWN21.2 设计模式模式应用观察者模式收集器作为事务的观察者监听提交/回滚事件命令模式AfterTransactionSyncAction接口封装延迟执行的操作收集器模式在事务内累积多个动作事务结束后批量执行策略模式提交动作和回滚动作分开注册、分开执行1.3 解决的核心问题在Transactional方法内有些操作必须在事务提交后才能执行发 MQ 消息事务未提交就发消息消费者可能查到旧数据释放分布式锁事务未提交就解锁其他线程读到未提交的中间状态调外部接口事务回滚了但外部接口已调用无法撤销缓存更新事务未提交就更新缓存缓存与数据库不一致1.4 Java 核心知识点说明函数式接口AfterTransactionSyncAction只有一个方法支持 LambdaLinkedList保持注册顺序执行方法引用lock::unlock作为AfterTransactionSyncAction传入注博客https://blog.csdn.net/badao_liumang_qizhi二、包结构xxx.xxx.lib.transaction ├── AfterTransactionSyncAction.java // 提交后动作接口 ├── AfterTransactionRollbackSyncAction.java // 回滚后动作接口 └── AfterTransactionActionCollector.java // 核心收集器注册到事务同步器注意无spring.factories不是自动配置库。使用时在业务代码中直接new并注册。三、核心实现流程Transactional 方法内 │ ├─→ new AfterTransactionActionCollector() │ ├─→ collector.addCommitSyncAction(() - sendMqMessage()) // 注册提交后动作 ├─→ collector.addCommitSyncAction(lock::unlock) // 注册释放锁动作 ├─→ collector.addRollbackSyncAction(() - compensate()) // 注册回滚补偿动作 │ ├─→ TransactionSynchronizationManager │ .registerSynchronization(collector) // 注册到Spring事务管理器 │ ├─→ 业务逻辑执行数据库操作等 │ └─→ 事务结束 │ ├── 提交成功 → afterCommit() │ └── 按顺序执行所有 commitActionssendMqMessage() → lock.unlock() │ ├── 回滚 → afterCompletion(STATUS_ROLLED_BACK1) │ └── 按顺序执行所有 rollbackActionscompensate() │ └── afterCompletion() 最终清理 └── commitActions.clear() rollbackActions.clear()四、通用示例代码4.1 AfterTransactionSyncAction提交后动作接口packagecom.example.transaction;/** * 事务提交后执行的动作接口. * 函数式接口支持Lambda表达式. */FunctionalInterfacepublicinterfaceAfterTransactionSyncAction{voidexecute();}4.2 AfterTransactionRollbackSyncAction回滚后动作接口packagecom.example.transaction;/** * 事务回滚后执行的动作接口. * 用于补偿操作如撤销已发的外部通知等. */FunctionalInterfacepublicinterfaceAfterTransactionRollbackSyncAction{voidexecute();}4.3 AfterTransactionActionCollector核心收集器packagecom.example.transaction;importjava.util.LinkedList;importjava.util.List;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.transaction.support.TransactionSynchronizationAdapter;/** * 事务后置动作收集器. * * 在 Transactional 方法内使用收集需要在事务提交/回滚后执行的动作. * * 核心价值 * 1. 保证 MQ 消息在事务提交后才发送消费者能查到已提交数据 * 2. 保证分布式锁在事务提交后才释放其他线程读到一致数据 * 3. 支持事务回滚时执行补偿逻辑 * * 使用方式 * 1. new 一个 collector * 2. addCommitSyncAction() 注册提交后动作 * 3. addRollbackSyncAction() 注册回滚后动作 * 4. TransactionSynchronizationManager.registerSynchronization(collector) 注册 */publicclassAfterTransactionActionCollectorextendsTransactionSynchronizationAdapter{privatestaticfinalintSTATUS_COMMITTED0;privatestaticfinalintSTATUS_ROLLED_BACK1;privatestaticfinalintSTATUS_UNKNOWN2;privatefinalListAfterTransactionSyncActioncommitActionsnewLinkedList();privatefinalListAfterTransactionRollbackSyncActionrollbackActionsnewLinkedList();privatefinalLoggerloggerLoggerFactory.getLogger(getClass());/** * 添加事务提交后执行的动作等同于 addCommitSyncAction. */publicvoidaddSyncAction(AfterTransactionSyncActionaction){logger.debug(add action to thread local: {},action);commitActions.add(action);}/** * 添加事务提交后执行的动作. */publicvoidaddCommitSyncAction(AfterTransactionSyncActionaction){logger.debug(add commit sync action: {},action);commitActions.add(action);}/** * 添加事务回滚后执行的动作. */publicvoidaddRollbackSyncAction(AfterTransactionRollbackSyncActionaction){logger.debug(add rollback sync action: {},action);rollbackActions.add(action);}/** * 事务提交成功后回调. * 按注册顺序依次执行所有 commitActions. */OverridepublicvoidafterCommit(){if(!commitActions.isEmpty()){for(AfterTransactionSyncActionaction:commitActions){logger.debug(begin to execute after commit action: {},action);action.execute();}}else{logger.debug(no commitActions to be executed);}}/** * 事务完成后回调无论提交还是回滚. * 如果是回滚status1执行所有 rollbackActions. * 最后清理所有已注册的动作. */OverridepublicvoidafterCompletion(intstatus){logger.debug(after transaction with status {}, commit action size: {}, rollback action size: {},status,commitActions.size(),rollbackActions.size());if(statusSTATUS_ROLLED_BACK!rollbackActions.isEmpty()){logger.debug(the transaction rolled back! begin to execute roll back actions);for(AfterTransactionRollbackSyncActionaction:rollbackActions){logger.debug(begin to execute after rollback action: {},action);action.execute();}}// 清理防止内存泄漏commitActions.clear();rollbackActions.clear();}}4.4 pom.xmlStarter 侧projectgroupIdcom.example/groupIdartifactIdexample-transaction-action-starter/artifactIdversion1.0.0/versionpackagingjar/packagingdependenciesdependencygroupIdorg.springframework/groupIdartifactIdspring-tx/artifactIdscopeprovided/scope/dependencydependencygroupIdorg.slf4j/groupIdartifactIdslf4j-api/artifactIdscopeprovided/scope/dependency/dependencies/project五、引入方使用5.1 添加依赖dependencygroupIdcom.example/groupIdartifactIdexample-transaction-action-starter/artifactIdversion1.0.0/version/dependency5.2 使用示例1事务提交后发 MQServicepublicclassOrderService{ResourceprivateOrderMqSenderorderMqSender;Transactional(rollbackForException.class)publicvoidcreateOrder(OrderDtoorderDto){// 1. 创建收集器并注册到事务管理器AfterTransactionActionCollectorcollectornewAfterTransactionActionCollector();TransactionSynchronizationManager.registerSynchronization(collector);// 2. 执行数据库操作OrderorderorderRepository.save(convertToEntity(orderDto));// 3. 注册事务提交后发MQLambda 写法collector.addCommitSyncAction(()-{orderMqSender.sendOrderCreatedMessage(order.getId());});// 4. 其他业务逻辑...// 事务提交后MQ消息才会发出如果事务回滚消息不会发}}5.3 使用示例2事务提交后释放分布式锁ServicepublicclassStockService{ResourceprivateDistributedLockProviderdistributedLockProvider;Transactional(rollbackForException.class)publicvoiddeductStock(IntegeritemId,Integerqty){// 1. 获取锁StringlockKeystock_deduct_itemId;DistributedLocklockdistributedLockProvider.getLock(lockKey);lock.tryLock(TimeUnit.MINUTES,1);// 2. 注册事务提交后释放锁AfterTransactionActionCollectorcollectornewAfterTransactionActionCollector();TransactionSynchronizationManager.registerSynchronization(collector);collector.addCommitSyncAction(lock::unlock);// 方法引用// 3. 执行库存扣减stockRepository.deduct(itemId,qty);// 事务提交后锁才释放 → 其他线程读到的一定是已提交的数据// 事务回滚 → afterCompletion 中 clear 动作列表但锁不会主动释放需要等待过期}}5.4 使用示例3提交和回滚分别处理ServicepublicclassPaymentService{Transactional(rollbackForException.class)publicvoidprocessPayment(PaymentDtodto){AfterTransactionActionCollectorcollectornewAfterTransactionActionCollector();TransactionSynchronizationManager.registerSynchronization(collector);// 调用第三方支付已扣款StringpaymentIdthirdPartyPayService.charge(dto.getAmount());// 保存支付记录paymentRepository.save(newPayment(paymentId,dto));// 事务提交后通知下游发货collector.addCommitSyncAction(()-{deliveryService.triggerDelivery(dto.getOrderId());});// 事务回滚后调第三方退款补偿collector.addRollbackSyncAction(()-{thirdPartyPayService.refund(paymentId);});}}5.5 使用示例4结合分布式锁完整场景ServicepublicclassBatchDeliveryService{Transactional(rollbackForException.class)publicvoidbatchConfirmDelivery(DeliveryParamsDtoparams){// 获取锁Stringkeybatch_delivery_params.getMemberId();DistributedLocklockdistributedLockProvider.getLock(key,TimeUnit.MINUTES,10);lock.tryLock(TimeUnit.MINUTES,8);// 注册事务后释放锁AfterTransactionActionCollectorcollectornewAfterTransactionActionCollector();TransactionSynchronizationManager.registerSynchronization(collector);collector.addCommitSyncAction(lock::unlock);// 执行批量发货业务// ... 写入发货单、写入扩展表is_fixed_delivery_date、写出库单 ...// 事务提交后发MQ通知collector.addCommitSyncAction(()-{deliveryMqSender.sendToYc(params.getDeliveryRecordCode());});}}六、关键设计总结设计要点实现方式收益事务与副作用解耦副作用延迟到事务提交后执行MQ 消费者读到已提交数据外部调用不会因回滚而产生脏数据提交/回滚分离commitActions rollbackActions 两个列表不同事务结果执行不同逻辑支持补偿有序执行LinkedList 保持注册顺序多个动作按业务预期顺序执行自动清理afterCompletion 中 clear 两个列表防止内存泄漏零配置无 spring.factories直接 new 使用极简无侵入函数式接口支持 Lambda 和方法引用代码简洁优雅最小依赖仅依赖 spring-tx slf4j任何 Spring 事务项目都能用

相关新闻

SpringBoot中基于 OAuth2 + Spring Security 的用户认证上下文工具库(UC Token Util)Starter 实践

SpringBoot中基于 OAuth2 + Spring Security 的用户认证上下文工具库(UC Token Util)Starter 实践

SpringBoot中基于 OAuth2 Spring Security 的用户认证上下文工具库(UC Token Util)Starter 实践一、涉及的技术知识点 1.1 OAuth2 JWT 认证体系知识点说明OAuth2 协议标准的授权框架,支持 password/client_credentials/refresh_token 等授权…

2026/7/24 2:00:03 阅读更多 →
智能体系统设计模式解析与应用实践

智能体系统设计模式解析与应用实践

1. 智能体设计模式全景概述在当今AI技术快速发展的背景下,智能体(Agent)系统已成为解决复杂问题的关键架构。不同于传统的单次模型调用,智能体系统通过自主决策、多步骤工作流管理和工具使用能力,能够处理更加开放和动态的任务场景。设计模式…

2026/7/24 2:00:03 阅读更多 →
抖音算法突变应对方案:用AI自动化实现流量翻倍的5个关键动作(2024最新版)

抖音算法突变应对方案:用AI自动化实现流量翻倍的5个关键动作(2024最新版)

更多请点击: https://intelliparadigm.com 第一章:抖音算法突变的本质洞察与AI应对范式迁移 抖音算法并非线性演进的静态规则集,而是一个由实时用户反馈、多模态内容理解、跨域行为建模与商业目标动态博弈共同驱动的闭环强化学习系统。近期…

2026/7/24 1:59:03 阅读更多 →

最新新闻

AI智能体技术解析与学习路径指南

AI智能体技术解析与学习路径指南

1. 智能体(AI Agent)技术全景解析在2023年ChatGPT引爆AI热潮后,智能体技术正以惊人的速度渗透到各行各业。不同于传统AI模型的被动响应模式,智能体具备自主感知、决策和执行能力,能够像数字员工一样完成复杂任务链。根…

2026/7/24 2:17:08 阅读更多 →
基于Markdown与MCP协议的项目管理平台实战指南

基于Markdown与MCP协议的项目管理平台实战指南

基于 Markdown 的项目管理平台:从 CLI 到 MCP 协议的完整实战指南在软件开发团队中,项目管理工具的选择往往决定了协作效率。传统项目管理平台虽然功能丰富,但常常伴随着复杂的界面、臃肿的功能和陡峭的学习曲线。最近,基于 Markd…

2026/7/24 2:17:08 阅读更多 →
AI Agent工程化实践:从模型开发到系统稳定性的关键挑战

AI Agent工程化实践:从模型开发到系统稳定性的关键挑战

1. 面试官为什么开始关注Harness Engineering?最近半年,我面试了7家AI相关企业的Agent开发岗位,发现一个明显趋势:80%的技术面试都会涉及Harness Engineering(工程化约束)相关问题。这反映出行业正在从纯模…

2026/7/24 2:17:08 阅读更多 →
DA3-GIANT单目深度估计技术解析与应用

DA3-GIANT单目深度估计技术解析与应用

1. Depth Anything 3(DA3-GIANT)技术解析单目深度估计领域最近迎来重大突破,Depth Anything 3(代号DA3-GIANT)以全新架构刷新了业界基准。这个由香港大学和字节跳动联合研发的模型,在NYU Depth V2和KITTI等…

2026/7/24 2:17:08 阅读更多 →
基于YOLOv10的固体废物智能识别系统设计与优化

基于YOLOv10的固体废物智能识别系统设计与优化

1. 项目背景与核心价值固体废物识别检测系统是当前环保科技领域的热门研究方向。随着垃圾分类政策的深入推进和循环经济理念的普及,传统的人工分拣方式已无法满足日益增长的废物处理需求。这个基于YOLOv10的智能识别系统,正是为了解决这一痛点而生。我在…

2026/7/24 2:17:08 阅读更多 →
Thesean Ship端点测试版:LLM调用成本减半的架构优化实践

Thesean Ship端点测试版:LLM调用成本减半的架构优化实践

这次我们来看一个值得关注的 LLM 服务优化项目——Thesean 推出的 Ship 端点测试版。这个项目的核心价值很直接:让 LLM 的调用成本固定减半,同时保持稳定的服务质量。对于需要频繁调用大语言模型的企业或个人开发者来说,成本控制和服务稳定性…

2026/7/24 2:16:07 阅读更多 →

日新闻

用Highcharts 创建可拖拽三维散点立方体3D图表

用Highcharts 创建可拖拽三维散点立方体3D图表

该案例基于Highcharts scatter3d 三维散点图实现空间立方体散点可视化,核心特色:三维 X/Y/Z 三轴空间,所有散点分布在 0~10 立方体空间内;散点使用径向渐变实现立体 3D 圆球质感;支持鼠标 / 触屏拖拽画布,…

2026/7/24 0:00:29 阅读更多 →
AppCertDlls:进程创建路径上的 DLL 入口

AppCertDlls:进程创建路径上的 DLL 入口

AppCertDlls:进程创建路径上的 DLL 入口 AppCertDlls 位于 HKLM\System\CurrentControlSet\Control\Session Manager\AppCertDlls。本文的程序功能是只读列出这个键在 64 位和 32 位注册表视图中的全部值,并显示每条值的来源、名称、类型和可安全显示的数…

2026/7/24 0:00:29 阅读更多 →
我的编程之路:第一篇博客

我的编程之路:第一篇博客

大家好,我是一名编程初学者,同时这也是我编程学习之路上的第一篇博客。在这里,我想要向大家介绍我的一些想法和规划。a.自我介绍我是一个刚刚接触编程的新手,目前在学习c语言,我对编程世界充满了强烈的好奇。当然&…

2026/7/24 0:00:29 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/22 8:58:19 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/24 1:23:39 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/23 17:49:47 阅读更多 →

月新闻