首页 > 解决方案 > 从多个用户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 个(只有一个用户可以订购)

标签: phpsqlsql-updatesql-insert

解决方案


处理并发性的一种方法是更改​​逻辑,并通过尝试访问表来启动进程updateproducts并使用一个where确保请求数量可用的子句,如下所示:

UPDATE products 
SET available_quantity = available_quantity - 1
WHERE 
    product_id = :id
    AND product_active = 1
    AND available_quantity > 0

然后,您可以检查受查询影响的行数:

  • 如果有一行受到影响,则表示该签出确实成功;然后您可以完成其余的流程(创建订单和订单详细信息记录)

  • 如果没有行受到影响,则检出失败;不创建订单

使用这种技术,您可以让数据库为您处理并发,并且保证您销售的产品永远不会超过可用数量。


推荐阅读