支付幂等:一锁二判三更新

一、前言

古人云:"一命;二运;三风水;四积功德;五读书。"

回顾过去的一年,公司的故障报告里 防重复问题 反复出现,比如:

  • 人民币钱包付款:只付款了一次,但是系统付了两笔,两笔的创单间隔时间是5s
  • 领取奖励金重复:重复获得 -> 盗刷
  • 疑似重复入账:平台背后的支付机构汇款异常,一笔交易打款两次(导致给客户入账两笔资金)
  • 等等

此类问题归类于没有做好幂等,那么幂等是什么

对同一操作重试任意多次,系统的最终状态,以及对外可观测的结果不变;为容错与重试而生。

  • 网络问题 / 前端操作抖动,造成重复提交,后台系统仅处理一次。

针对这类问题,有一个口诀:一锁二判三更新

  • 一锁:先对同一业务唯一单号加锁,串行化并发请求,避免同时修改同一份数据。
  • 二判:拿到锁后先判定是否已处理过/是否允许处理(幂等判重、状态判定、业务约束)。已处理则直接返回历史结果,不再执行。
  • 三更新:要落库幂等记录(带唯一幂等键),重复请求直接命中并返回相同结果。

案例分析:资金安全

以下是3个案例场景。

案例一:防重复扣款(不要轻易换单)

用户下单场景:

  • 易错 1:向账户系统,重复扣余额
  • 易错 2:重复向渠道扣款

问题:如果扣款 / 扣余额步骤超时了,该怎么办?

即出现了中间态,可以先查询请求情况,再重试。

  • 超时关单不可取:可能账务系统那扣款成功了。

Tips:避免重复有如下准则

  • 扣钱时:先扣钱再处理业务
  • 加钱时:先处理业务再加钱

案例二:防重复入账

海外电商平台入账:平台收款

  • 各大银行通过 H2H方式/人工上传,解析入账文件,获得客户的银行入账流水信息
  • 根据店铺信息定期拉取账期数据
  • 根据亚马逊账单和银行流水,符合匹配规则后,进行入账

存在特殊入账:

  1. 银行钱先到,账期数据还没到
  2. 亚马逊 API 授权关闭了,但钱打过来了
  3. 等等

疑似重复入账:平台背后支付机构汇款异常,一笔交易打款两次,即入金 2 笔。

  • 后续银行直接按ACH debit 将资金从账户中扣除

案例三:防重复结算

支付场景是实时的,但要将钱打给商户要通过清结算系统。

  • 易错:重复结算、重复打款。

解决:

  1. 上下游单据一致性核对:支付 - 清结算,单据一致核对(笔数、金额)。
  2. 打款拦截:打款前规则判断,比如:每日打一次款。

二、实际工作中使用

实际工作中,通常采用组合拳方式:分布式锁 + 数据库兜底

  • "分布式锁"实现幂等:因为锁丢失 / 续约失败,仍有重复
  • 幂等表:用唯一约束 + 去重表做最终保障

代码如下:

1、分布式锁,一般使用 Redis,封装对应锁工具

java 复制代码
@RedisLock(lockName = "order", key = "#req.reqId")
public OrderResponse order(Req req) {
    // 业务处理
}

2、幂等表

java 复制代码
public void saveOrder(TradeOrder tradeOrder) {
    Order order = (Order) tradeOrder;
    transactionTemplate.execute(status -> {
        //幂等表
        repeatRepository.save(order);
        //订单表
        orderRepository.saveOrder(order);
    });
}
相关推荐
技术小泽1 天前
搜索系统架构入门篇
java·后端·算法·搜索引擎
+VX:Fegn08951 天前
计算机毕业设计|基于springboot + vue酒店预约系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
踏浪无痕1 天前
告警的艺术:从 node_exporter 指标到生产级规则
后端·架构·监控
源码获取_wx:Fegn08951 天前
基于springboot + vue酒店预约系统
java·vue.js·spring boot·后端·spring
我想问问天1 天前
【从0到1大模型应用开发实战】03|写一个可解释的RAG规则检索器
后端·aigc
豆浆Whisky1 天前
6小时从0到1:我用AI造了个分片SQL生成器
后端·sql·ai编程
风的归宿551 天前
解构内存迷宫:串联虚拟地址、页表与内存使用(一)
后端
武子康1 天前
大数据-202 sklearn 决策树实战:criterion、Graphviz 可视化与剪枝防过拟合
大数据·后端·机器学习
李广坤1 天前
ShardingSphere-JDBC 实战指南
后端