为什么会重复扣费?
- 客户误操作点了两次
- 客户跳到支付平台界面,但是支付平台反抗充值界面有超时,客户又发起了一次购买流程。
方案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之后然后做操作是属于悲观锁方案。
也有另外一种乐观锁,