複数のユーザーからのデータを更新する効果sql php

2020-05-23 php sql sql-update sql-insert

質問があります オンラインストアを作っています。 利用可能な数量属性を持つ製品を提供します 特定の製品に1つの数量しかありません。 2人のユーザーがログインし、この要素をカートに追加しました。 両方とも同時にチェックアウトしました(私は、画面で2つのブラウザーを分割し、同時にチェックアウトボタンを押してこれを実行しようとしています)。 この場合、製品のチェックアウトが1人のユーザーだけで成功することをどのように管理できますか?

  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つの製品がユーザー1の注文テーブルに追加され、他の2つがuser2の注文テーブルに追加されます)。これは間違っています。この場合、1人のユーザーだけがチェックアウトを成功させ、2人目のユーザーに警告メッセージを表示します)

Ajaxコード:

$(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つだけであることを考慮していることを忘れないでください(1人のユーザーのみが注文できるのはこのためです)。

Answers

同時実行性を処理するアプローチは、ロジックを変更し、次のように、要求された数量が利用可能であることを保証するwhere句を使用して、 productsテーブルをupdateすることからプロセスを開始することです。

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

次に、クエリの影響を受ける行数を確認できます。

  • 1つの行が影響を受けた場合、チェックアウトが成功したことを意味します。その後、残りのプロセスを実行できます(注文と注文詳細レコードを作成します)

  • 影響を受ける行がない場合、チェックアウトは失敗しました。注文を作成しないでください

この手法を使用すると、データベースに並行処理を処理させ、使用可能な製品よりも多くの製品を販売しないことが保証されます。

Related