この記事では、Laravel に関する関連知識をお届けします。主に、Laravel Eloquent モデルにおけるオプティミスティック ロックの実装について紹介します。コード例もあります。興味のある方は、以下をご覧ください。役立つことを願っています。手伝う。
app/Utils/Traits ディレクトリに OptimisticLockTrait.php を作成します。コードは次のとおりです:
namespace App\Utils\Traits;use Illuminate\Database\Eloquent\Builder;trait OptimisticLockTrait{ /** * @var array $optimisticConditions * @var array $bindings */ protected $optimisticConditions, $bindings; /** * @var string $optimisticConditionRaw */ protected $optimisticConditionRaw; /** * save 时增加乐观锁条件 * @param Builder $builder */ protected function performUpdate(Builder $builder) { if (!empty($this->optimisticConditions)) { foreach ($this->optimisticConditions as $field => $value) { if (is_array($value)) { $count = count($value); if ($count >= 3) { switch (strtoupper($value[1])) { case 'IN': $builder->whereIn($value[0], $value[2]); break; case 'NOT IN': $builder->whereNotIn($value[0], $value[2]); break; case 'BETWEEN': $builder->whereBetween($value[0], $value[2]); break; case 'NOT BETWEEN': $builder->whereNotBetween($value[0], $value[2]); break; default: $builder->where($value[0], $value[1], $value[2]); } } else { $builder->where($value); } } else { $builder->where($field, $value); } } } // 原始条件注入 if ($this->optimisticConditionRaw) $builder->whereRaw($this->optimisticConditionRaw, $this->bindings); return $this->clearOptimistic()->perFormUpdating($builder); } /** * updating with optimistic * * @param Builder $builder * @return bool */ protected function perFormUpdating(Builder $builder) { // If the updating event returns false, we will cancel the update operation so // developers can hook Validation systems into their models and cancel this // operation if the model does not pass validation. Otherwise, we update. if ($this->fireModelEvent('updating') === false) { return false; } // First we need to create a fresh query instance and touch the creation and // update timestamp on the model which are maintained by us for developer // convenience. Then we will just continue saving the model instances. if ($this->usesTimestamps()) { $this->updateTimestamps(); } // Once we have run the update operation, we will fire the "updated" event for // this model instance. This will allow developers to hook into these after // models are updated, giving them a chance to do any special processing. $dirty = $this->getDirty(); $res = 0; if (count($dirty) > 0) { $res = $this->setKeysForSaveQuery($builder)->update($dirty); $this->syncChanges(); $this->fireModelEvent('updated', false); } return !empty($res); } // 清除乐观锁条件 function clearOptimistic() { $this->optimisticConditions = null; $this->optimisticConditionRaw = null; return $this; } // 设置乐观锁条件字段名列表 function setOptimistic(array $optimisticConditions) { $this->optimisticConditions = $optimisticConditions; return $this; } // 设置乐观锁原始条件字段名列表 function setOptimisticRaw(string $optimisticConditionRaw, array $bindings = []) { $this->optimisticConditionRaw = $optimisticConditionRaw; $this->bindings = $bindings; return $this; }}
オプティミスティック ロックの使用手順
1. モデル (Models) またはモデルの親クラスで
/** * App\Models\BaseModel * @mixin \Eloquent * @method static \Illuminate\Database\Eloquent\Builder|BaseModel newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|BaseModel newQuery() * @method static \Illuminate\Database\Eloquent\Builder|BaseModel query() */class BaseModel extends Model{ use OptimisticLockTrait;}
を使用します。 2. 使用方法:
$ord = Order::find(1); $ord->payment_status = 1; if(!$model->setOptimistic(['payment_status' => 0]))->save()) throws new Exception('订单已付过款了');
または元の SQL メソッドを使用します:
$ord = Order::find(1); $ord->payment_status = 1; if(!$model->setOptimisticRaw('payment_status = ?',[1]))->save()) throws new Exception('订单已付过款了');
同一オブジェクトが小さい場合 複数の更新を伴う場合はロック状態を解除できる
$ord->clearOptimistic();
以上が実際の開発で一般的に使用され必要となる楽観的ロックの実装方法です。
推奨学習: 「laravel ビデオ チュートリアル」
以上がLaravel Eloquent モデルでの楽観的ロックの実装の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。