一些MySql查询PHP条件

时间:2014-06-04 11:02:00

标签: php race-condition

背景: 我想在PHP-Webapp中匹配用户。 当用户进入特定页面时,他将被放入虚拟池中。 该池实现为以下MySql表:

"search-table": id|userId|parameter

每个用户都在检查,如果该表中有其他用户,谁准备匹配。(准备匹配=相同的参数)。检查是通过AJAX-Request每隔x秒对我的PHP控制器完成的。 (AJAX-Request重复,直到找到匹配或用户离开)。

如果此查询返回有效的合作伙伴userId,则另一个查询应该执行INSERT到第二个表。

"matching-table": id|firstUser|secondUser

插入后,"搜索表"应删除匹配用户的条目。

如何保证,对于同一个用户"将不会有两个插入内容,因为有些用户正在执行"检查"同时查询? - >竞争条件。

例如: UserA,userB和UserC位于" search-table"中。 -UserA:他的AJAX请求返回UserC -UserB:他的AJAX请求也返回userC

-UserA:创建插入"匹配表" with firstUser = UserA和secondUser = UserC -UserB:还会在" matching-table"中创建一个插入,但是使用firstUser = UserB和secondUser = UserC -UserA:删除"搜索表"使用" userA"的条目和" userC"

=> UserB不应该能够创建INSERT,因为UserA已经选择了UserC。

我怎么能意识到这一点? 我的实际代码是:

try
{   
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $dbh->beginTransaction();   

    $stmt =  $dbh->prepare("SELECT id FROM [...]");

    $stmt->bindParam(1, [...]);

    if($stmt->execute())
    {
        if($row = $stmt->fetch())
        {
            $matchID = $row['id'];
            //check if parameter/id is ok
            $checkD = $this->checkId($matchID);

            if($checkD)
            {
                return '-1';
            }
            else
            {      

                //Create entry in "matching-table"
                $stmt = $dbh->prepare("INSERT INTO [...]");

                $stmt->bindParam(1,[...]);
                $stmt->execute();

                //Delete Users from "serach-table"
                $stmt = $dbh->prepare("DELETE [...]");

                $stmt->bindParam(1,[...]);
                $stmt->execute();

                $dbh->commit();

                return $matchID;                            
            }
        }
        else
        {
            return '-1';
        }
    }
    else
    {
        return '-1';
    }       
} catch(Exception $e)
{
    $dbh->rollBack();
    return '-1';
}

我怎样才能锁定"表,当用户从" search-table"获得有效结果时他想创建"匹配表"条目 - 所以没有其他用户也可以创建该条目吗?

0 个答案:

没有答案