Spring Cloud框架下分布式事务:跨服务数据回滚简易方案问询
最简易处理方案:主动补偿(反向调用)
在Spring Cloud场景下,要解决服务A保存成功、服务B保存失败后的A数据回滚问题,最轻量化的实现方式是主动触发反向补偿,无需引入分布式事务框架这类重依赖,具体实现如下:
1. 给服务A新增幂等性回滚接口
针对服务A的保存操作,新增一个用于回滚/删除数据的接口,核心要求是保证幂等性:
- HTTP方法:
DELETE - 路径示例:
/api/a/{bizId}(bizId为业务唯一标识,比如保存数据时生成的主键或业务编码) - 逻辑:先校验对应业务数据是否存在且处于有效状态,存在则删除/标记为无效;不存在或已回滚则直接返回成功,避免重复调用报错
2. 改造服务C的调用逻辑
在服务C中按顺序执行调用,一旦服务B出现失败(包括业务报错、调用异常),立即触发服务A的回滚操作,伪代码示例:
// 调用服务A保存数据 Result aSaveResult = aFeignClient.save(dataA); if (!aSaveResult.isSuccess()) { return Result.fail("服务A保存失败"); } // 获取A保存后的业务标识 String bizId = aSaveResult.getData().getBizId(); try { // 调用服务B保存数据 Result bSaveResult = bFeignClient.save(dataB); if (!bSaveResult.isSuccess()) { // B保存失败,触发A回滚 aFeignClient.rollback(bizId); return Result.fail("服务B保存失败,已回滚服务A数据"); } } catch (FeignException | RuntimeException e) { // B调用异常,同样触发A回滚 aFeignClient.rollback(bizId); return Result.fail("调用服务B异常,已回滚服务A数据", e); } return Result.success("数据保存成功");
3. 关键注意事项
- 幂等性必须保证:A的回滚接口要避免重复调用导致的异常,比如通过
bizId查询数据状态,已处理过的请求直接返回成功 - 回滚失败兜底:如果调用A的回滚接口失败,建议通过本地日志记录关键信息,配合定时任务自动重试,或者触发告警通知人工介入,避免数据不一致
- 场景限制:该方案适合业务逻辑简单、对一致性要求不是极端严格的场景;如果是金融级强一致场景,才需要考虑Seata等分布式事务框架
内容的提问来源于stack exchange,提问作者edenl
相关产品推荐
相关产品推荐

