Laravel Eloquent模型中樂觀鎖的實現

本篇文章給大家帶來了關于laravel的相關知識,其中主要跟大家介紹laravel eloquent模型中樂觀鎖的實現,有代碼示例,感興趣的朋友下面一起來看一下吧,希望對大家有幫助。

在app/Utils/Traits目錄下創建OptimisticLockTrait.php,代碼如下:

namespace AppUtilsTraits;use IlluminateDatabaseEloquentBuilder;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)或模型父類使用

/** * AppModelsBaseModel * @mixin Eloquent * @method static IlluminateDatabaseEloquentBuilder|BaseModel newModelQuery() * @method static IlluminateDatabaseEloquentBuilder|BaseModel newQuery() * @method static IlluminateDatabaseEloquentBuilder|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();

? 版權聲明
THE END
喜歡就支持一下吧
點贊6 分享