PHP PDO事务以防止双重开支?
我有一个“积分”表,其中有一个“玩家”列和一个“fpp”列,分别表示一些可使用的积分类型 我需要一个函数,当某个玩家的余额>=x fpp可用时,该函数将从该玩家的余额中减去x fpp。如果玩家的余额减少,函数应返回true;如果资金不足,函数应返回false 我需要防止任何双重支出的情况,据我所知,我需要交易。使用PDO,我总结了以下内容:PHP PDO事务以防止双重开支?,php,mysql,pdo,transactions,acid,Php,Mysql,Pdo,Transactions,Acid,我有一个“积分”表,其中有一个“玩家”列和一个“fpp”列,分别表示一些可使用的积分类型 我需要一个函数,当某个玩家的余额>=x fpp可用时,该函数将从该玩家的余额中减去x fpp。如果玩家的余额减少,函数应返回true;如果资金不足,函数应返回false 我需要防止任何双重支出的情况,据我所知,我需要交易。使用PDO,我总结了以下内容: function subFPP($player,$x){ global $dbh; $didSub = false; $dbh-&g
function subFPP($player,$x){
global $dbh;
$didSub = false;
$dbh->beginTransaction();
$stmt = $dbh->prepare("SELECT fpp FROM points WHERE player=?");
$stmt->execute(array($player));
$row = $stmt->fetch();
if($row && $row[0]>=$x){
$stmt = $dbh->prepare("UPDATE points SET fpp=fpp-? WHERE player=?");
$stmt->execute(array($x,$player));
$didSub = true;
}
if($dbh->commit()){
return $didSub;
}
return false;
}
这似乎是按照预期的方式进行的,但我以前从未处理过事务,我不确定这是否符合我的需要。如果同时对此函数进行了两次调用,则只应执行一次(假设x超过可用余额的一半)。这能保护我避免双重消费吗?还是我搞砸了什么?有什么改进吗
此外,我看到的所有PDO事务片段都包含try/catch,并在错误块中包含回滚调用。没有理由在这里回滚一次插入/更新?为什么不添加
WHERE player=?和fpp>?
这是玩家ID和他们试图花费的金额?这样,除非他们有足够的资金,否则查询将无法运行。哇,好建议。我是否仍然需要使用单个查询(先读后写)开始/提交事务,或者mysql会为我处理这些事务?为单个查询创建一个事务真的没有意义,它们的定义是原子的。事务用于将多个语句分组在一起。