phpはredisと組み合わせて高並発下の買い占め、秒殺機能を実現する

3654 ワード

買い占め、秒殺は今よく見られる応用シーンです.主に解決しなければならない問題は2つあります.1高同時性がデータベースに与える圧力2競合状態で在庫の正確な減少(「超過販売」の問題)をどのように解決するか.1つ目の問題では、Redisなどのデータベースの直接操作を避けるためにキャッシュで買い占めを処理することが容易に考えられます.2つ目の問題に重点を置きます.
一般的な書き方:
対応商品の在庫を照会し、0より大きいかどうかを確認してから注文を生成するなどの操作を行いますが、在庫が0より大きいかどうかを判断する際に、高く発下すると問題があり、在庫量がマイナスになります

0){//         
    $order_sn=build_order_no();
    //      
    $sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price) 
    values('$order_sn','$user_id','$goods_id','$sku_id','$price')";  
    $order_rs=mysql_query($sql,$conn); 
    
    //    
    $sql="update ih_store set number=number-{$number} where sku_id='$sku_id'";
    $store_rs=mysql_query($sql,$conn);  
    if(mysql_affected_rows()){  
        insertLog('      ');
    }else{  
        insertLog('      ');
    } 
}else{
    insertLog('    ');
}
?>

シナリオ1:在庫フィールドnumberフィールドをunsignedに設定し、在庫が0の場合、フィールドが負数にならないためfalseが返されます.
//    
$sql="update ih_store set number=number-{$number} where sku_id='$sku_id' and number>0";
$store_rs=mysql_query($sql,$conn);  
if(mysql_affected_rows()){  
    insertLog('      ');
}

シナリオ2:mysqlのトランザクションを使用して、操作の行をロックします.
0){
    //     
    $order_sn=build_order_no();    
    $sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price) 
    values('$order_sn','$user_id','$goods_id','$sku_id','$price')";  
    $order_rs=mysql_query($sql,$conn); 
    
    //    
    $sql="update ih_store set number=number-{$number} where sku_id='$sku_id'";
    $store_rs=mysql_query($sql,$conn);  
    if(mysql_affected_rows()){  
        insertLog('      ');
        mysql_query("COMMIT");//       
    }else{  
        insertLog('      ');
    }
}else{
    insertLog('    ');
    mysql_query("ROLLBACK");
}
?>