首页 > 解决方案 > 并发更新

问题描述

我正在构建一个处理Wallet的应用程序。我有这个钱包的提和提
当此钱包的 + 或 - 发生更新时,我遇到了问题。
看场景:

用户提现,系统检索此钱包的余额,如下所示:

select * from Wallet where idUser = x;

所以上面的这个查询返回了钱包,并且 * 得到了“余额”列并像这样

wallet.balance += amount;

在此之后,我将进行更新以插入此钱包的新“余额”并执行此操作

update Wallet set balance = balanceVar where idWallet = x;

直到这里一切看起来都很好,但是当我们同时处理现金进出时,这种情况下更好的情况是什么。
把这个放在队列中?
更新时锁定表?
这是我第一次处理这样的系统,我真的很困惑该怎么做。

标签: mysqlsqlalgorithmconcurrency

解决方案


您的SELECTthenUPDATE方案直接导致竞争条件,其中两个进程可以选择相同的数据,然后执行相同的更新,从而导致发生两个更新但只记录一个更新的不一致。

避免这种情况的方法是使用原子操作(即不能分割的操作)。

在您的情况下,您应该直接更新钱包:

update Wallet set balance = balance+10 where idWallet = 'x';

在另一个进程可以执行另一个更新之前,此更新将完全完成。

你可以用这个想法走得更远。对于提款,只有当余额大于或等于提款时,您才能更新钱包:

update Wallet set balance = balance-10 where idWallet = 'x' and balance >= 10;

您可以测试ROW_COUNT()一下操作是否成功。PHP 提供mysqli_affected_rows()PDOStatement::rowCount()用于此目的。


推荐阅读