你们是怎么解决资金安全问题的

比如说余额更新,防止重复

悲观锁性能很差,我目前用的是乐观锁,但是用的是 User::where (‘id’, $user->id)->where (‘version’, $user->version)->update ([]);
这种方式

感觉不是很优雅,看手册,发现有一个原子锁,Cache::lock () 这个方案你们觉得怎么样

《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
讨论数量: 4
yybawang

我就是用的 Cache::lock () 目前用了几年也没发现什么问题,用的 docker 单个 redis 容器服务

  • 放一段一直在用的代码仅供参考,这段代码是所有加减款都必须经过这个方法,所以只在加入这个 lock,下面的代码类似于乐观锁,利用缓存键加入一个钱包 ID,只会在这个钱包 ID 业务下 lock,其它钱包 ID 是另一个 lock 键锁互不影响

  • if 判断不那么优雅,按照文档说法应该放到 catch 里,但没啥问题,我也不想去改这个逻辑了。又不是不能用(图先欠着)

    // 出账钱包扣款
              $out_purse = null;
              $out_lock = Cache::lock('EBank@_transfer:' . $out_purse_id);
              try {
                  $out_purse = $out_lock->block(50, function () use ($out_purse_id, $amount) {
                      $var = FundPurse::where(['id' => $out_purse_id, 'status' => 1])->where('balance', '>=', $amount)->decrement('balance', $amount);
                      // 未修改返回修改行数为0
                      if (!$var) {
                          return false;
                      }
                      return FundPurse::find($out_purse_id);
                  });
                  optional($out_lock)->release();
              } catch (LockTimeoutException $e) {
    
              } finally {
                  optional($out_lock)->release();
              }
              if ($out_purse === null) {
                  abort(422, '转出钱包查询超时');
              }
              if ($out_purse === false) {
                  abort(422, '转出钱包扣款失败,余额不足或账户被禁用');
              }
3年前 评论
SupeRod 3年前

@yybawang 感谢无私分享啊,我研究研究

3年前 评论

Cache 驱动是 Redis 的话 本质就是 Redis分布式锁

3年前 评论