이 기사는 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; }}
Optimistic Lock 사용 지침
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 중국어 웹사이트의 기타 관련 기사를 참조하세요!