【发布时间】:2018-01-07 17:28:11
【问题描述】:
我正在开展一个项目,用户将用真钱购买“硬币”。他们还可以在交易系统中以真钱出售这些代币。他们甚至可以将硬币发送给其他用户。这将用 PHP 编写。我了解 mysql 事务,但我不是 100% 确定这需要 100% 来自并发错误。我创建了伪代码,我认为其中存在缺陷。
function withdraw($id, $amount_to_withdraw) {
$ret = false;
$balance = $db->getBalanceById($id);
$this->makeSureAmountIsNotNegative($amount_to_withdraw);
$new_balance = $balance - $amount_to_withdraw;
if ($new_balance >= 0.00) {
try {
$db->startTransaction();
// THIS IS WHERE THE FLAW IS!!!
$db->do("UPDATE account SET balance = ? WHERE id = ?", array($new_balance, $id));
$db->commit();
$ret = true;
} catch (Exception $e) {
$db->rollback();
}
}
return $ret;
}
据我了解,在 PHP 中可能会在此完全完成之前执行另一个请求,并且可能会将余额设置为低于零和其他错误的并发错误。 我如何编写此代码以使其免受这些错误的影响。 我需要行级mysql锁定吗:
// ROW LEVEL LOCKING FOR UPDATE
$balance = $db->select("SELECT balance FROM account WHERE id = ? FOR UPDATE;", array($id));
谢谢 布赖恩
【问题讨论】:
-
你的意思是写
SET balance = ?? -
是的,谢谢..已编辑
标签: php mysql transactions locking banking