当调用外部接口发生异常、服务器宕机或杀死进程时如何保证数据一致性

调用外部接口发生异常时数据一致性解决方案

这里提供一个一劳永逸的解决方案

设计思路:

外部接口多采用交易接口+结果查询接口的方式,基于这种形式的接口提供以下解决方案。

  1.根据流水号标识一笔交易请求,另外本地要提供rollback方法

  2.模板类记录请求日志,日志状态在本地事务更新

 3.定时任务扫描日志表异常或超时记录,然后调用外部查询接口进行补偿,对成功请求更改日志状态

  4.如果外部接口返回失败,则调用rollback方法进行回滚

  5.如果外部接口实现了密等性,可根据流水号(类全局事务ID)进行重试

该方案实现了对外部接口调用的密等性

日志表结构

根据具体业务增加字段

 

CREATE TABLE `trade_log` (

  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',

  `serial_num` varchar(32) DEFAULT '' COMMENT '流水号',

  `message` varchar(1000) DEFAULT '' COMMENT '请求报文',

  `log_status` varchar(10) DEFAULT 'INIT' COMMENT '日志状态:INIT-初始化,LOCAL_SUC-本地事务成功,SUC-事务成功,FAIL-事务失败',

  `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

  `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',

  PRIMARY KEY (`id`),

  UNIQUE KEY `uk_serial_num` (`serial_num`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

流程图

当调用外部接口发生异常、服务器宕机或杀死进程时如何保证数据一致性_第1张图片

 

扩展延伸

分布式事务问题可基于BASE理论解决,现在较流行的TCC和基于可靠消息的最终一致性解决方案都是对BASE理论的实现

 

TCC实现有tcc-transaction(gitbub)、hmily(码云)、fescar

可靠消息最终一致性:新版本的RocketMq支持事务的回查,可保证消息不丢失

你可能感兴趣的:(Java架构组件使用)