php下单扣除余额问题

问题描述

客户端执行下单操作,后台接受到订单信息,一般的做法都是查询余额以及对比商品的价格,假如余额小于商品价格则不能够下单成功,但是我出现了,连续下入两单的操作,并且扣除客户余额未负的情况。

相关代码

// 请把代码文本粘贴到下方(请勿用图片代替代码)
我的逻辑代码为。
IF(客户余额<商品价格){
执行下单操作,记录下单日志。事务提交的
}

你期待的结果是什么?实际看到的错误信息又是什么?

请问下我的逻辑是否有问题,为什么会出现连续下单,扣除余额为负的情况

阅读 4.9k
6 个回答

下单就扣除余额了吗?不是要确认支付么?

接口的冥等性是常见的现象,前端在发起下单时最好做等待响应,这段时间内屏蔽发起下单的触发。

考虑到前端BUG的存在或者不可控因素,前端发起订单的时候最好携带一个唯一码,这个唯一码可以是后端提前生成,图方便也可以前端生成,在发起订单的时候后端检查这个唯一码在订单表中是否存在,来校验是否为重复的发起。

你上面的事务逻辑只能保证你的订单和扣款是正常的,但是这种极端的情况,两个订单请求都是同时到达服务端,这时两者查询都是符合扣款条件的,你的事务只能保证订单和扣款正常更新。

IF(客户余额<商品价格){ 这里的价格是什么呢,string?? 还是int 分

  • 既然余额不足就不能下单,为什么不在下单前就把客户余额查出来,下单操作前就在前端进行验证,当然保险起见后端同样需要加入验证。
  • 业务上如果没有负数余额的需求,可以把字段设为无符号。
  • 下单的提交在后台加上验证,防止短时同一操作重复提交相同数据。
  • 最重要的还是要找到程序bug

首先你确认你的代码对不对,你的想法对不代表你的代码对,其次考虑并发,数据库锁类型等问题

看一下sql语句,扣款方式使用的是 SET money = 100-80 还是SET money = money - 80;
前者在并发的情况下,不管下几单,money最终只会等于20.后者肯定能够扣完订单数对应的余额.

看样子是并发问题,你可以尝试使用redis的锁限制一下

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题