防止 Laravel 中的用户帐户同时提款

问题描述 投票:0回答:1

我想防止账户余额同时提取。 例如,当用户账户余额为500美元时不允许。两个提取 300 美元的并发请求会将用户余额更改为 -100 美元

用户表:

身份证 名字
1 约翰
2 大卫
3 新浪

我有一个名为 transactions 的表,如下所示:

身份证 用户 金额 平衡
1 约翰 +350 350
2 约翰 +250 600
3 约翰 -100 500
4 约翰 +400 900

通过查看上表,我们可以看到用户 John 的账户余额(通过添加金额列的值)为 $900

我创建了一个 API 将库存从一个用户转移到另一个用户

http://127.0.0.1:8000/api/v1/deposit/transfer/FromUser/ToUser/amount

如果我按如下方式运行 api 一次。交易表将会发生变化,如您所见

http://127.0.0.1:8000/api/v1/deposit/transfer/John/David/500

身份证 用户 金额 平衡
4 约翰 -500 400
5 大卫 +500 500

到目前为止我们没有问题。但是如果上面的api被两个用户同时执行,John的账户余额就会为负数

假设该api被两个用户同时调用。发生以下情况

  1. http://127.0.0.1:8000/api/v1/deposit/transfer/John/David/500
  2. http://127.0.0.1:8000/api/v1/deposit/transfer/John/Sina/600
身份证 用户 金额 平衡
1 约翰 +350 350
2 约翰 +250 600
3 约翰 -100 500
4 约翰 +400 900
5 约翰 -500 400
6 大卫 +500 500
7 约翰 -600 300
8 新浪 +600 600

现在约翰的总金额栏是多少? -100 美元,这是灾难的开始!

我想在 Laravel 中防止这种情况发生。我可以使用的最佳方法是什么? (我的数据库是mysql)

php mysql laravel transactions
1个回答
0
投票

我个人觉得明显的

MySql
锁定解决方案可能很难做你真正想做的事情。

Laravel
对于这个确切的问题有原子锁。它需要某些缓存驱动程序才能工作,并且您必须弄清楚应该锁定的密钥应该是什么。据我了解,您可能必须锁定约翰和大卫等等。与数据库锁定相比,此解决方案提供了更多控制。

Cache::lock('john', 30)->block(28, function () {
        Cache::lock('david', 30)->block(28, function () {
            // do account operation
        });
});

在此示例中,它将保持锁定 30 秒或直到关闭完成后释放。等待 28 秒直到锁被释放。这里的问题也与负载有关,因为依赖于流量,您将不得不削弱您的解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.