我正在运行一个短信发送网站。当用户发送消息时,需要从其账户中扣除1个积分。
但是,当用户快速提交请求时,账号不会正确递减。例如,用户从10个积分开始,快速提交3个请求,但数据库将余额存储为9个积分而不是7个!
下面是我更新数据库的方法:
$sql5="update sms set sms='$remaining_sms' WHERE username='$session_username'";
$result5=mysql_query($sql5);
发布于 2015-09-28 16:01:31
有几个请求都在争先恐后地将他们认为正确的值放入数据库。因此,两个请求同时到达,它们都将信用级别读取为'10',发送一条消息,然后都写入'9‘作为新的信用级别。
相反,让数据库为您递减它
$sql5="update sms set sms=sms-1 WHERE username='$session_username'";
$result5=mysqli_query($link, $sql5);
这将保持正确的信用级别,但在重负载下,这可能会变成负值,因此用户可以发送比他们的信用更多的消息!
为了防止这种情况,您需要一个查询,它既可以减少帐户,也可以告诉他们是否有任何信用。像这样简单的事情就能达到目的:
UPDATE sms SET sms=sms-1 WHERE sms>0 AND username=?
然后检查是否使用mysqli_affected_rows或类似技术更新了行-如果没有更新的行,则它们已失信。如果是,那么他们有信用,并且成功地扣除了它。
有关避免这些类型的竞争条件的更多技术,请参阅see this question
https://stackoverflow.com/questions/32818187
复制相似问题