php - 从多个用户sql php更新数据的效果
问题描述
我有一个问题,我正在做一个在线商店。它提供具有可用数量属性的产品让我们假设某个产品只有 1 个可用数量。2 个用户已登录并将此元素添加到购物车。他们都同时签出(我试图通过在屏幕上拆分 2 个浏览器并同时按下结帐按钮来做到这一点。)在这种情况下,如何管理产品结帐仅对一个用户成功?
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if(isset($_POST['qty_array'])&&isset($_POST['ids_array'])){
$order_address=$_POST['addressCart'];
$ids_array=$_POST['ids_array']; //this is array of product ids in the cart
$qty_array=$_POST['qty_array']; // this is array of quantities in the cart
$date=date("Y-m-d H:i:s");
$j=0;
$x=0;
foreach($ids_array as $id){
$query = "SELECT available_quantity from products where product_id='$id' AND product_active=1";
$result = mysqli_query($db,$query);
$row = mysqli_fetch_array($result);
$qty1=$qty_array[$j];
if($row['available_quantity']==0 || $qty1>$row['available_quantity']){
$x++;
}
$j++;
}
if($x!=0){
$msg="unable_checkout";
echo $msg;
}
else{
$bool=mysqli_query($db,"INSERT INTO order_table(customer_id,order_date,order_address)
VALUES ('$customerID','$date','$order_address')") or die("".mysqli_error($db));
$order_id=mysqli_insert_id($db);
if($bool){
$k=0;
foreach($ids_array as $id){
$query2 = "SELECT * from products where product_id='$id' AND product_active=1";
$result2 = mysqli_query($db,$query2);
$row2 = mysqli_fetch_array($result2);
$qty_available=$row2['available_quantity'];
$qty=$qty_array[$k];
$unitprice=$row2['product_price'];
$discount=$row2['product_discount'];
if($qty<=$qty_available && isset($_SESSION['cartProds']) && $qty_available!=0 ){
mysqli_query($db,"INSERT INTO order_details(order_id,product_id,unitprice,discount,quantity)
VALUES ('$order_id','$id','$unitprice','$discount','$qty')") or die("".mysqli_error($db));
$newqty=$qty_available-$qty;
mysqli_query($db,"UPDATE products SET available_quantity='$newqty' WHERE product_id='$id'");
}
$k++;
}
}
$msg="checkedout_successfully";
//unset inserted order :
unset($_SESSION['cartProds']);
$_SESSION['nOfProds']=0;
echo $msg;
}
}
当其中一个数量等于零时,我需要停止提交并且不插入任何内容。
我得到的是,如果 2 个用户想要同时结帐 3 个相同的产品(一个产品被添加到用户 1 的订单表中,另外 2 个被添加到用户 2 的订单表中......这是错误的,我想要在这种情况下,只有一个用户才能成功结帐,并为第二个用户发出警告警报消息)
阿贾克斯代码:
$(document).ready(function() {
$("#enableAddress").change(function(){
if($("#enableAddress").prop("checked") == true){
$("#addressCart").prop('disabled',false);
}
else{
$("#addressCart").prop('disabled',true);
}
});
$("#checkoutBtn").click(function(){
var ids_array = [];
$('input[name^=checkoutHidden]').each(function(){
ids_array.push($(this).val());
});
var qty_array = [];
$('input[name^=quantity]').each(function(){
qty_array.push($(this).val());
});
var telCart = $("#telCart").val();
var addressCart = $("#addressCart").val();
$.ajax({
type: "POST",
url: "../phpOnly/checkOut.php",
data: { ids_array:ids_array, qty_array:qty_array,addressCart:addressCart},
success: function(msg) {
// alert(msg);
if(msg=="checkedout_successfully"){
// $("#orderMsg").fadeIn(3000);
// $("#cartBody").fadeOut(2000);
// $("#nOfProdsSpan").text('0');
alert(msg);
}
else if(msg=="unable_checkout"){
// window.location.href="#";
// $("#inavailableMsg").fadeIn(1000);
alert(msg);
}
}
});
});
});
别忘了我考虑到可用数量只有 1 个(只有一个用户可以订购)
解决方案
处理并发性的一种方法是更改逻辑,并通过尝试访问表来启动进程update
,products
并使用一个where
确保请求数量可用的子句,如下所示:
UPDATE products
SET available_quantity = available_quantity - 1
WHERE
product_id = :id
AND product_active = 1
AND available_quantity > 0
然后,您可以检查受查询影响的行数:
如果有一行受到影响,则表示该签出确实成功;然后您可以完成其余的流程(创建订单和订单详细信息记录)
如果没有行受到影响,则检出失败;不创建订单
使用这种技术,您可以让数据库为您处理并发,并且保证您销售的产品永远不会超过可用数量。
推荐阅读
- javascript - 在javascript中必须始终检查未定义/空值的返回是否正常?
- python - 比较和计算两个数字之间的相同数字
- rest - base64 编码图像上传是一种不好的做法吗?
- apigee - Apigee 传递授权标头
- javascript - 使用 jQuery 向生成的 HTML 表添加标题行和时间列
- java - 如何创建自包含的 Java 应用程序?
- node.js - 如何在nodejs中导入webpack目标生成的main之外的其他文件?
- javascript - 如何将“Enter 键”分配给 onclick 事件?
- excel-formula - 在一个工作簿中使用多个工作表中的 sumif
- python - 使用自定义表单字段时出现 AttributeError