您的当前位置:首页 >人工智能 >优雅实现多系统一致性补偿方案 正文
时间:2025-11-05 15:52:58 来源:网络整理编辑:人工智能
前言我们在开发的过程中,如果一个业务操作需要本地写MYSQL数据以及对第三方系统做写操作,那么这种流程就涉及到分布式系统一致性的问题,然而并非所有系统都能使用成熟的分布式事务方案。案例说明以一个财务报
我们在开发的优雅过程中,如果一个业务操作需要本地写MYSQL数据以及对第三方系统做写操作,实现那么这种流程就涉及到分布式系统一致性的多系问题,然而并非所有系统都能使用成熟的性补分布式事务方案。
以一个财务报账业务为例,偿方涉及到的优雅系统如下:
系统名
作用
实现方案
单据系统
申请单内容以及凭证的生成
JAVA
BPM
实现流程的运转
购买成熟系统(例如:泛微)
SAP
财务凭证
购买成熟系统
详细解释下各系统作用:
单据系统:财务报账,会提交很多信息(例如:报账事由、实现报账金额与明细)。多系同时也会生成财务凭证(不了解凭证也没关系,性补它就是偿方给财务人员看的东西,对技术人员来说就是优雅数据库的一堆数据)。BPM系统:非常成熟的实现流程管理系统,以非常直观的多系方式来实现流程的搭配,不了解的性补可以自行百度扫盲。在此案例中,偿方需要使用BPM的两个能力:1)调用API,审核通过 2)调用API,获取流程的待审人。香港云服务器SAP系统:财务专用系统,不用过多了解,只要知道在财务审核完成后,会将单据系统生成的凭证数据通过API调用的方式发送给SAP即可。“审核通过”业务流程当审核人员审核通过时,大致流程如下:
保存业务数据+记录审核日志调用BPM接口,审核通过调用BPM接口,获取最新待审人如果没有待审人,说明已经审完,生成凭证并推送SAP代码如下:
图片
图片
如图所示,如果在1和2出现异常,由于有事务的存在,操作1内的几条mysql写操作会被回滚,因此所有数据都没有任何变化。
但如果1和2正常执行,操作3发生异常,操作1的数据会因为事务回滚,但操作2并不能。因此整个系统会出现一个很诡异的现象:单据系统内,没有任何日志记录,用户操作的数据也没有保留下来,但BPM那边却已经审核通过了,这在任何正常流程中,都是不可能出现的状态。云服务器提供商
对于用户而言,他在页面会收到报错,然后可能会再次点击“审核通过”,而此时BPM那边却显示,流程已经走到下一个节点,该用户无权限操作。
问题分析根本原因其实不难,因为MYSQL事务只能管他自己,没法控制第三方系统。
一个字:拆!
对于分布式系统,没有任何人能保证远程调用不出问题,因此在做设计时,就必须能够对这种情况做出应对。
上面的操作,打包放进一个大事务就是根因,因此方案就是将大事务拆开,在拆分时,需要遵循以下几个原则:
小事务内,尽量只有一个远程写操作该远程写操作放到方法最后,保证在其返回成功后就能立刻提交事务小事务可能会因为某些原因失败,因此需要机制来进行重试整体思路就是这样:
图片
基于以上原则,改动如下:
第一步,新建一张任务表:
复制CREATE TABLE `transaction_job` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 主键, `type` varchar(255) NOT NULL COMMENT 任务类型, `data` varchar(255) NOT NULL COMMENT 任务数据, `error_message` varchar(255) DEFAULT NULL COMMENT 错误信息, `context` varchar(255) DEFAULT NULL COMMENT 任务上下文(主要是保存当前操作人), `create_time` bigint(20) NOT NULL COMMENT 创建时间, `update_time` bigint(20) NOT NULL COMMENT 更新时间, `retry_times` int(11) NOT NULL DEFAULT 0 COMMENT 重试次数, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=事务任务表;1.2.3.4.5.6.7.8.9.10.11.作用:保存小事务的关键数据到data字段中,以保证通过该字段,就能正确执行小事务。另外也需要保存当前操作人的高防服务器信息context。
第二步,通过定时任务,查出transaction_job表中未完成的数据,并执行对应的操作,这里通过简单的策略模式,将框架代码和业务代码做了分离
首先是框架代码核心逻辑。
扫描任务
图片
执行任务

这是一个策略模式接口,每个小事务就封装一个独立的实现类。
图片
其中更新待审人的任务实现如下,其实就是把那部分代码复制过来。
图片
第三步,改造业务代码,不再一次性把流程写完,而且是在第一个小事务中,顺便往transaction_job中插入一条数据,以执行第二个小事务。
图片
其中步骤2(插入任务数据的代码)的具体实现如下(transactionJobService.create)。
图片
上述方案种,除第一个事务外,后续事务都是通过定时任务来执行的,因此这些事务都存在一定的延迟,用户体验不好,解决办法也非常简单,只需要利用好Spring对于事务的生命周期管理,稍微改造一下插入任务的方法(transactionJobService.create)。
图片
这是Spring提供的工具类,afterCommit()方法会在事务提交后执行,因此加上这段代码后,思路就变成了这样。
图片
如果小事务顺利执行,会立刻将该任务改为“成功”,因此从用户端是感受不到延迟的。
注意可能存在添加任务后,定时任务也立刻扫描到了这条数据,同一任务就会被主线程与定时任务线程同时执行,所以实际应用中需要考虑这个问题(比如:加锁再执行,执行前再检查数据库状态)。
目前只给出了解决思路的核心,但真实项目中,还添加了不少额外功能,以后会逐渐更新进来。
灵越游匣Speed(畅快游戏,快意生活,游匣Speed助你纵享极速世界)2025-11-05 15:38
电脑显示键盘驱动错误解决方案(如何处理电脑键盘驱动错误及常见问题解答)2025-11-05 15:26
解决电脑显示1706错误的方法(解析1706错误的原因及如何修复)2025-11-05 15:04
免费数据恢复教程(恢复误删除文件、格式化硬盘的简易方法)2025-11-05 14:58
电脑电源改装音响教程(利用电脑电源将音响升级为高品质音响)2025-11-05 14:32
电脑键盘教程大全(从基础操作到高级技巧,让您的打字更高效)2025-11-05 14:28
新手拍摄剪辑教程电脑推荐(选择适合新手的剪辑电脑,帮助你轻松入门视频剪辑)2025-11-05 14:05
用衣柜拆分电脑排版,让工作更高效(将电脑工作区划分清晰,提高生产力)2025-11-05 13:51
教你如何正确包装显卡(显卡包装教程,从选材到操作一应俱全,细节决定成败)2025-11-05 13:37
PE启动盘使用教程(使用PE启动盘实现电脑故障快速修复与数据恢复)2025-11-05 13:07
电脑忘记开机密码的简单解决方法(忘记密码?别担心,这里有帮助!)2025-11-05 15:44
如何进行BIOS备份教程(轻松学会BIOS备份,保障您的计算机安全)2025-11-05 15:20
dataland显卡的性能与特点(探索dataland显卡的强大性能和创新特点)2025-11-05 15:15
快乐星球电脑教程(以游戏化体验进入电脑世界,让学习变得快乐有趣)2025-11-05 14:56
电脑音响支架安装教程(轻松安装,享受高品质音乐体验)2025-11-05 14:33
使命召唤8电脑操作教程(掌握技巧,驰骋战场)2025-11-05 14:32
378.78驱动带来的960性能提升(细腻画质与流畅体验的完美结合)2025-11-05 14:15
轻松掌握电脑操作技巧(快速上手,高效办公)2025-11-05 14:08
YADU空气净化器的使用体验与评价(探索YADU空气净化器的功能和效果,解析其适用性及性价比)2025-11-05 14:04
用衣柜拆分电脑排版,让工作更高效(将电脑工作区划分清晰,提高生产力)2025-11-05 13:41