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

悲观锁性能很差,我目前用的是乐观锁,但是用的是 `User::where (‘id’, $user->id)->where (‘version’, $user->version)->update ([]);`
这种方式感觉不是很优雅,看手册,发现有一个原子锁,`Cache::lock ()` 这个方案你们觉得怎么样?

回答处理

  1. 放一段一直在用的代码仅供参考,这段代码是所有加减款都必须经过这个方法,所以只在加入这个 lock,下面的代码类似于乐观锁,利用缓存键加入一个钱包 ID,只会在这个钱包 ID 业务下 lock,其它钱包 ID 是另一个 lock 键锁互不影响
  2. 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, '转出钱包扣款失败,余额不足或账户被禁用');
      }

转自:https://learnku.com/laravel/t/61510

标签: none

添加新评论