欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

PHP-MYSQL怎么实现买东西扣钱流程(细节问题一大堆)?

程序员文章站 2022-05-07 20:04:47
...
假设用户花费金钱余额兑换1个‘糖’这种虚拟商品,金钱余额和用户拥有‘糖’的个数分别记录在不同的表上,那么我们要做的是,扣除用户金钱的同时,在用户的虚拟物品表中‘糖’的数量+1。假设任何用户'糖'数上限为99

先说下目前小弟的思路:

*先select查询用户账上的金钱余额(SQL语句1)
*比较金钱余额和1个‘糖’价格,如果余额足够那么继续(PHP逻辑实现)
*事务开始
*update金钱余额,令其减去1个‘糖’的价格。这里出现问题A:是直接update成扣除‘糖’价之后的余额(即PHP先算出余额),还是让MYSQL做字段减法?(SQL语句2)
*select用户‘糖’数(SQL语句3)
*如果上一条select无结果,那么insert一条该用户'糖'的记录,数量为此次购买的'糖'数;如果已有该用户的‘糖’记录,那么update'糖'数,令其加上1。这里出现问题B:因为单个用户的'糖'数上限为99,我需要用PHP逻辑判断‘糖’数+1以后是否超过上限99,然而如果在SQL语句1和3中没有‘for update’锁表,那么结合问题A,一旦该用户同时发出2个买‘糖’请求,就可能出现实际上‘糖’数超过了上限99(比如达到了100)
*最后事务提交

所以最终的问题还有2个:
C:类似这种消耗一种资源,换取另一种资源的逻辑,在select某个资源数的时候都一定要‘select...for update’加锁吗?(不先select又无法进行钱是否足够或者'糖'是否数量超限的逻辑判断,select后再update又怕select到的数据中途被改)
D:上述流程有办法简化吗?

或者有没有关于这种问题的详尽的文章,如能分享不胜感激。


回复讨论(解决方案)

求助!!!!

你不就怕用户连续操作会出现并发问题么,那你就在用户点一次的时候,js控制按钮不可点,后台处理完了返回结果成功后,再解除按钮的锁定

mysql事物处理

你不就怕用户连续操作会出现并发问题么,那你就在用户点一次的时候,js控制按钮不可点,后台处理完了返回结果成功后,再解除按钮的锁定


前端确实是这么做的。。但是后端也应该考虑到单用户并发的问题啊

这东西要保证万无一失就必须得用事务, 要么失败回滚, 在么成功提交

必须使用事务处理。

先套上事务,然后select for update取出当前库存,如果足够就插入一条记录到日志表,然后update库存完成扣减,最后释放掉事务。

可以加我QQ讨论:120848369,最近也在准备做这个,目前方案就是事务+锁,单个商品的库存性能可能不太好。