为什么会重复扣费?
- 客户误操作点了两次
- 客户跳到支付平台界面,但是支付平台反抗充值界面有超时,客户又发起了一次购买流程。
方案1:for update加锁
之前在坦桑尼亚做TTCL项目的时候遇到代理商充值计费系统返回系统报错。
跟sql日志发现,给用户充值的时候先会给该用户select *** from *** for update上锁,然后进行充值,充值成功后会commit解锁。
比如充值操作的时间是1秒,侧面可以看出该操作出现的原因是,一内内也就是充值订单完成前,又有一笔充值,但是该用户已经上锁,导致操作失败。
for update大量用于存在高并发并且对于数据的准确性很有要求的场景。
比如涉及到金钱、库存等。一般这些操作都是很长一串并且是开启事务的。充值去用户有100RMB,计划充值20元,而1秒内女朋友帮他充值50元进行了update将余额更新为150元了,而原来事务还没有结束,当本身的充值20成功后会基于原来的balance+recharge_amount,变为120,就会有问题。所以需要for upate 进行数据加锁防止高并发时候数据出错。
弊端:上锁解决了高并发时的覆盖update问题,但是也造成了另一笔业务意义上没毛病操作报错。
有没有类似的解决方式呢?其实我们上述的for update之后然后做操作是属于悲观锁方案。
也有另外一种乐观锁,就是只select balance from ***,然后更新的时候where条件加个and current_balance=balance,满足条件再update,commit.
电商也有两种比较经典的方案:

本文探讨了支付并发时可能导致的重复扣款问题及其解决方案,包括使用for update加锁、退款流程、幂等性设计,并介绍了乐观锁、京东的退款流程和银行收银台的幂等性要求。同时提到了接口幂等性的实现方法,如通过订单ID检查和token机制。最后,文章提到了系统复杂性导致的问题,强调综合技术、产品设计和运营支持的重要性。


被折叠的 条评论
为什么被折叠?



