> 백엔드 개발 > PHP 튜토리얼 > PHP 높은 동시성 테스트: 재고 과판매 방지 사례 연구

PHP 높은 동시성 테스트: 재고 과판매 방지 사례 연구

WBOY
풀어 주다: 2023-04-10 22:46:01
앞으로
7330명이 탐색했습니다.

이전 글 "PHP에서 높은 동시성으로 인한 상품 재고 과판매 방지 방법"에서 높은 동시성으로 인한 재고 과판매 방지에 대한 관련 내용을 동시 테스트에 대해 살펴보겠습니다. 모든 사람에게 도움이 되기를 바랍니다.

PHP 높은 동시성 테스트: 재고 과판매 방지 사례 연구

이 글은 "PHP의 높은 동시성에서 제품 재고가 과매출되는 것을 방지하는 방법" 테스트 사례를 기반으로 작성되었습니다. 추천 학습: "PHP 학습 튜토리얼"

1. 일반 주문

동시 테스트 중 제품 테이블 ID =1 이름 = Daohuaxiang Rice store = 15

请求总数30 每次10个并发
ab -n 30 -c 10 http://xxxxx.top/code/the_limit/add_order.php
로그인 후 복사

결과:

15개의 성공적인 재고 감소가 있었습니다. 매장재고는 -7 8번으로 재고부족으로 판단됩니다. (마이너스 재고번호는 부정확하여 허용되지 않습니다.)

2. 미서명 모드

다시 상품 테이블 ID = 1 이름 = 다오화샹쌀가게로 조정 = 15

请求总数30 每次10个并发
ab -n 30 -c 10 http://xxxxx.top/code/the_limit/unsigned.php
로그인 후 복사

결과:

재고 감소가 15번 성공했습니다. 매장 재고가 -6으로 나타났습니다. 9번은 재고가 부족하다고 판단되었습니다(마이너스 재고 수치는 부정확하므로 허용되지 않습니다).

업데이트를 쿼리문에 추가하는 것만으로는 잠금 효과가 거의 없습니다.

3. MySQL 트랜잭션, 잠금 작업 행

제품 테이블 ID = 1 이름 = Daohuaxiang Rice store = 15

请求总数30 每次10个并发
ab -n 30 -c 10 http://xxxxx.top/code/the_limit/ACID.php
로그인 후 복사

결과:

15번의 재고감축에 성공하였고, 매장재고가 마이너스 15로 나타나지 않았습니다. 재고가 부족한 것으로 판단됩니다(마이너스 재고번호는 부정확하여 허용되지 않습니다)

거래 추가 효과 ab -n 3000 -c 1000 동시성을 견딜 수도 있습니다

4. 비차단 파일 독점 잠금

  • 차단 형식

  • 비차단 형식

효과는 부정적이지는 않지만 성능 측면에서는 트랜잭션 > 차단 > 비- 블로킹

5. redis 대기열

코드는 이전 낙관적 잠금 버전에서 약간 조정되었습니다

<?php
$redis =new Redis();
$redis->connect("127.0.0.1", 6379);
$redis->auth(&#39;PASSWORD&#39;);
$redis->watch(&#39;sales&#39;);//乐观锁 监视作用 set()  初始值0
$sales = $redis->get(&#39;sales&#39;);
//var_dump($sales); exit;

db();
global $con;
// 查询商品信息
//$product_id = 1;
//$sql = "select * from products where id={$product_id}";
//$result = mysqli_query($con, $sql);
//$row = mysqli_fetch_assoc($result);
//$store = $row[&#39;store&#39;];
// 库存
$n = 15;
if ($sales >= $n) {
    insertLog(&#39;库存为0 秒杀失败&#39;);
    exit(&#39;秒杀结束&#39;);
}

//redis开启事务
$redis->multi();
$redis->incr(&#39;sales&#39;); //将 key 中储存的数字值增一 ,如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。
$res = $redis->exec(); //成功1 失败0

if ($res) {
    //秒杀成功
    $con = new mysqli(&#39;localhost&#39;,&#39;root&#39;,&#39;PASSWORD&#39;,&#39;dev&#39;);
    if (!$con) {
        echo "数据库连接失败";
    }

    $product_id = 1;// 商品ID
    $buy_num = 1;// 购买数量
    sleep(1);

    $sql = "update products set store=store-{$buy_num} where id={$product_id}";

    if (mysqli_query($con, $sql)) {
        echo "秒杀完成";
        insertLog(&#39;恭喜 秒杀成功&#39;);
    }

} else {
    insertLog(&#39;抱歉 秒杀失败&#39;);
    exit(&#39;抢购失败&#39;);
}

function db()
{
    global $con;
    $con = new mysqli(&#39;localhost&#39;,&#39;root&#39;,&#39;WOrd1234.*&#39;,&#39;dev&#39;);
    if (!$con) {
        echo "数据库连接失败";
    }
}

/**
 * 记录日志
 */
function insertLog($content)
{
    global $con;
    $sql = "INSERT INTO `order_log` (content) values(&#39;$content&#39;)";
    mysqli_query($con, $sql);
}
로그인 후 복사
ab -n 30 -c 10 http://xxxxxx.top/code/the_limit/optimistic\ _redis_lock.php
로그인 후 복사

최종 결론 동시성 문제의 우선순위를 지정하고 redis의 성능이 좋습니다

추천 학습: "PHP 비디오 튜토리얼"

위 내용은 PHP 높은 동시성 테스트: 재고 과판매 방지 사례 연구의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
php
원천:learnku.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿