首页 > 解决方案 > 处理来自并发 API 调用的条件 SELECT 和 UPDATE 查询

问题描述

我有一个系统,可以根据为用户定义的机会向用户提供不同类型的奖品。我有一个名为的列totalCount,其中包含可以授予的那种类型的总奖品数量,还有一个名为的列awardedCount,其中包含已授予的奖品数量。客户端调用特定的 API 来检查奖品。

在 API 逻辑中,首先我检查有多少可用的奖品类型,为此我检查 if (awardedCount < totalCount)。在这里,我得到了我传递给机会算法的奖品列表,并获得了特定类型的奖品作为回报。在此之后,我将更新该特定类型奖品的表格数据awardedCount = awardedCount + 1

在我对 API 进行多个并发调用之前,这一切正常。我通过拨打一百个并发电话进行了测试,并保持totalCount = 5. 授予的奖品比预期的要多很多倍,我在多个并发呼叫的测试中获得了 6 或 7 个奖品。我相信这是因为调用 API 的多个线程和从那里执行的 SQL 查询没有相应地同步,在这种情况下这是非常自然的。

代码如下:

public function claimPrize($criteria) {
    // Check login
    if(AuthHelper::loginStatus($criteria)) {

        // Get available prizes
        $availablePrizes = $this->getPrizes();

        // Award a prize
        $awardedPrize = $this->selectPrize($availablePrizes);

        // Update awarded prize
        $response = $this->updatePrize($awardedPrize);
    }
}

private function getPrizes() {
    $prizesQuery = DoctrineQuery::from('cms_prizes')
                    ->select('*')
                    ->addWhere('awardedCount < totalCount');

    $prizesAvailable = $prizesQuery->execute();

    return $prizesAvailable->toArray();
}

private function selectPrize($availablePrizes) {
    // Chance calculation done here
    return ChanceHelper::getPrize($availablePrizes);
}

private function updatePrize($awardedPrize) {
    $prizesQuery = DoctrineQuery::from('cms_prizes')
                    ->select('*')
                    ->addWhere('type = ?', array($awardedPrize['type']))
                    ->getFirst();

    $prizeModel = $prizesQuery->execute();

    if($prizeModel) {
        $prizeModel->awardedCount = $prizeModel->awardedCount + 1;
        
        $prizeModel->save();
    }
    
    return $prizeModel;
}

我需要一些关于如何处理这个问题的帮助。API 是用 PHP 编写的,我使用 MySQL 作为数据库。

PS:标题可能含糊不清,因为我想不出任何可以简单解释这个问题的东西。如果是这样,也请帮助我。

标签: phpmysqlapiconcurrency

解决方案


推荐阅读