掘金 后端 ( ) • 2024-05-17 10:12

theme: scrolls-light

壮岁旌旗拥万夫,锦襜突骑渡江初。

1 前言

在前文中,已经讲述了红包相关的业务,在本文中将讲述一个用户积分发放的场景。用户的积分发放在面向 C 端业务中是十分常见的,主要用户维护客户关系,提高用户粘性,发掘潜在的用户。用户积分的发放通俗的讲就是平台在特定业务场景下由商户或者平台商户给用户发送积分,即 B 端账户给 C 端账户发送积分,这个过程可能是批量操作,也可能是单笔操作。

2 业务分析

用户积分分发业务如下图所示,积分分发信息表记录发放的基本信息,分发日志表记录需要分发的C 端账户信息。在进行业务参数校验后,需要先记录分发的信息后,然后记录 C 端和 B 端的操作日志,待记录完成之后,先调用 B 端的批量出账接口,处理成功后修改 B 端日志操作表,而后调用 C 端的批量入账接口,处理业务完成后修改 C 端日志操作表。待两者成功完成后,需要修改积分分发信息表和积分分发日志表状态为成功,该批量或者单笔操作完成。如果中途有失败的情况,由于有信息表和操作表的存在,可以做到根据请求号做业务或者接口的幂等性。如果操作 C 端接口或者 B 端接口有一个失败,则另外一个需要进行撤销。

1695222160926.png

3 代码实现

示例以批量分发积分为例,每次积分分发时以批次号为唯一条件查询分发信息,如果分发信息存在,需要判断是否是终态(成功或者失败),终态的情况需要直接返回。如果是处理中的数据,则需要继续进行处理,保证业务的幂等性。由于入参都使用了参数校验,这里需要做的就是进行业务参数的校验,这里只做了分发金额的累加和传参的分发总金额对比,其实还需要添加B端和C端账户存在性的校验。 1695303895157.png

完成了参数校验后,需要先记录操作日志信息,然后执行积分分发的动作,最后修改数据库表,至此积分的批量分发完毕。

1695303937147.png

如下图所示,保存数据信息,需要执行分发批次信息和日志信息的构建,构建 C 端和 B 端日志,然后将四个操作放在一个事务中执行,保证业务的完整性。每条数据中都存在着状态信息,需要执行完成之后修改对应的状态,通过业务单号和对应的状态对其操作进行重试,保证业务的幂等性。

1695304035443.png

当数据完成保存后,需要进行积分发的操作,因为涉及到多个服务,这里没有采用分布式事务的解决方案,而是先记录操作日志,然后构建调用参数,先执行 B 端的批量出账,再执行 C 端的批量入账操作。如果两者都执行成功,则返回结果才成功,在执行出账和入账的操作后,需要修改操作表的数据状态。当所有的数据都完成,且状态修改完成后,返回积分分发成功。

1695304066266.png

总结

在本文中讲述了如何实现积分的分发,而且是使用批量分发的方式,核心思想就是在操作业务执行前先记录日志然后执行业务操作。完成业务操作后进行数据库状态的修改,然后逐级向上返回业务信息,最终通过数据库表状态和请求参数来实现业务的幂等性。以上代码均已完成并上传,项目 github 地址 springboot-auth