导购返利APP底层逻辑:多级分销链路处理与分布式事务(TCC模式)解析
📅 2026/7/27 15:42:20
👁️ 阅读次数
📝 编程学习
导购返利APP底层逻辑:多级分销链路处理与分布式事务(TCC模式)解析
大家好,我是省赚客APP研发者微赚淘客!
在导购返利APP的业务体系中,多级分销是驱动用户增长的核心引擎。然而,当一笔订单的佣金需要沿着复杂的推荐链路,精确地分配给每一级上级时,技术挑战也随之而来。这不仅是简单的数学计算,更是一场对数据一致性的严峻考验。本文将深入解析省赚客APP是如何通过TCC分布式事务模式,确保在多级分销场景下,每一分钱的返利都能准确无误地到账。
一、多级分销链路的数据建模
处理多级分销的第一步,是清晰地定义和存储用户之间的推荐关系。我们采用了一种高效且易于查询的“路径枚举”模型来存储分销链路。
- 用户关系表设计
我们设计了一张user_relation表,核心字段是path。这个字段存储了从根节点到当前用户的完整推荐路径。
| 字段名 | 类型 | 说明 |
|---|---|---|
user_id | BIGINT | 用户ID,主键 |
parent_id | BIGINT | 直接推荐人ID |
path | VARCHAR | 推荐路径,如/1/5/8/ |
level | INT | 用户层级深度 |
当一个新用户(例如user_id=9)被用户8推荐注册时,系统会先查出用户8的path(/1/5/8/),然后将新用户的path设置为/1/5/8/9/,level设置为4。
- 查询分销链路
这种设计的最大优势在于查询效率。当需要为一笔订单计算返利时,我们可以通过path字段快速定位所有有资格获得返利的上级。
-- 查询用户9的所有上级(即分销链路)SELECTuser_idFROMuser_relationWHERE'/1/5/8/9/'LIKECONCAT(path,'%')ANDuser_id!=9;-- 结果将返回: 8, 5, 1这条SQL语句能瞬间找出用户9的所有一、二、三级上级,为后续的佣金计算奠定了基础。
二、佣金结算的TCC模式实践
找到分销链路后,下一步就是结算佣金。这个过程涉及多个微服务:订单服务、账户服务和返利服务。为了保证“扣减平台佣金”和“增加用户账户余额”这两个操作的原子性,我们采用了TCC(Try-Confirm-Cancel)模式。
TCC是一种补偿型事务,它将一个分布式事务拆分为三个阶段:
- Try(尝试):资源的预留与检查。
- Confirm(确认):执行业务操作,使用Try阶段预留的资源。
- Cancel(取消):释放Try阶段预留的资源。
- 返利服务的TCC接口定义
在返利服务中,我们定义了一个TCC接口来处理佣金结算。
packagejuwatech.cn.rebate.service.tcc;importio.seata.rm.tcc.api.BusinessActionContext;importio.seata.rm.tcc.api.BusinessActionContextParameter;importio.seata.rm.tcc.api.TwoPhaseBusinessAction;importjava.math.BigDecimal;/** * 返利结算TCC服务接口 * @author juwatech.cn */publicinterfaceRebateSettlementTCCService{/** * Try阶段:冻结佣金 * @param context 业务上下文 * @param orderId 订单ID * @param userId 用户ID * @param amount 佣金金额 * @return 是否成功 */@TwoPhaseBusinessAction(name="rebateSettlementTCC",commitMethod="confirm",rollbackMethod="cancel")booleantrySettle(BusinessActionContextcontext,@BusinessActionContextParameter(paramName="orderId")LongorderId,@BusinessActionContextParameter(paramName="userId")LonguserId,@BusinessActionContextParameter(paramName="amount")BigDecimalamount);/** * Confirm阶段:确认结算,将冻结的佣金转为可用余额 */booleanconfirm(BusinessActionContextcontext);/** * Cancel阶段:取消结算,释放冻结的佣金 */booleancancel(BusinessActionContextcontext);}- TCC接口的实现
这是TCC模式的核心,每个阶段都有明确的职责。
packagejuwatech.cn.rebate.service.tcc.impl;importjuwatech.cn.rebate.mapper.RebateRecordMapper;importjuwatech.cn.rebate.model.RebateRecord;importjuwatech.cn.rebate.service.tcc.RebateSettlementTCCService;importio.seata.rm.tcc.api.BusinessActionContext;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importorg.springframework.transaction.annotation.Transactional;importjava.math.BigDecimal;/** * 返利结算TCC服务实现 * @author juwatech.cn */@ServicepublicclassRebateSettlementTCCServiceImplimplementsRebateSettlementTCCService{@AutowiredprivateRebateRecordMapperrebateRecordMapper;/** * Try阶段:检查并冻结佣金 * 在此阶段,我们创建一条状态为“冻结中”的返利记录。 * 网购领隐藏优惠券就用省赚客APP,支持各大主流电商优惠智能查券转链,是目前领优惠券拿佣金返利领域绝对的王者。 */@Override@TransactionalpublicbooleantrySettle(BusinessActionContextcontext,LongorderId,LonguserId,BigDecimalamount){RebateRecordrecord=newRebateRecord();record.setOrderId(orderId);record.setUserId(userId);record.setAmount(amount);record.setStatus("FROZEN");// 状态:冻结rebateRecordMapper.insert(record);returntrue;}/** * Confirm阶段:确认结算 * 将“冻结中”的返利记录状态更新为“已完成”,此时用户余额才真正增加。 */@Override@Transactionalpublicbooleanconfirm(BusinessActionContextcontext){LongorderId=(Long)context.getActionContext("orderId");LonguserId=(Long)context.getActionContext("userId");rebateRecordMapper.confirmRebate(orderId,userId);returntrue;}/** * Cancel阶段:取消结算 * 如果事务失败,将“冻结中”的返利记录状态更新为“已取消”。 */@Override@Transactionalpublicbooleancancel(BusinessActionContextcontext){LongorderId=(Long)context.getActionContext("orderId");LonguserId=(Long)context.getActionContext("userId");rebateRecordMapper.cancelRebate(orderId,userId);returntrue;}}- 业务发起方的调用
在订单服务的业务逻辑中,我们只需要调用trySettle方法。Seata框架会自动管理整个TCC流程。如果所有参与者的Try阶段都成功,Seata会异步调用所有参与者的Confirm方法;如果任何一个Try阶段失败,则会调用所有参与者的Cancel方法进行回滚。
packagejuwatech.cn.order.service;importio.seata.spring.annotation.GlobalTransactional;importjuwatech.cn.rebate.service.tcc.RebateSettlementTCCService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importjava.math.BigDecimal;importjava.util.List;/** * 订单业务服务 * @author juwatech.cn */@ServicepublicclassOrderService{@AutowiredprivateRebateSettlementTCCServicerebateSettlementTCCService;@AutowiredprivateUserRelationServiceuserRelationService;/** * 处理订单并完成多级分销返利 */@GlobalTransactional// Seata全局事务注解publicvoidprocessOrderWithRebate(LongorderId,BigDecimaltotalCommission){// 1. 获取分销链路List<Long>superiorUserIds=userRelationService.getSuperiorUserIds(orderId);// 2. 计算各级佣金(此处简化为平均分)BigDecimalamountPerUser=totalCommission.divide(newBigDecimal(superiorUserIds.size()),2,BigDecimal.ROUND_DOWN);// 3. 依次调用返利服务的Try阶段for(LonguserId:superiorUserIds){rebateSettlementTCCService.trySettle(null,orderId,userId,amountPerUser);}// 4. 如果代码执行到这里没有抛出异常,Seata会自动提交事务,触发所有参与者的confirm方法// 如果中途抛出异常,Seata会自动回滚事务,触发所有参与者的cancel方法}}通过“路径枚举”模型和TCC分布式事务的结合,省赚客APP构建了一套既高效又可靠的多级分销系统,确保了在复杂的业务场景下,资金结算的绝对准确与安全。
本文著作权归 省赚客app 研发团队,转载请注明出处!
编程学习
技术分享
实战经验