本篇文章给大家带来了关于laravel的相关知识,其中主要跟大家介绍laravel eloquent模型中乐观锁的实现,有代码示例,感兴趣的朋友下面一起来看一下吧,希望对大家有帮助。
在app/Utils/Traits目录下创建OptimisticLockTrait.php,代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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)或模型父类使用
1
2
3
4
5
6
7
8
/**
* 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、使用方法:
1
2
3
4
$ord = Order::find(1);
$ord->payment_status = 1;
if(!$model->setOptimistic([payment_status => 0]))->save())
throws new Exception(订单已付过款了);
或者使用原始SQL方式:
1
2
3
4
$ord = Order::find(1);
$ord->payment_status = 1;
if(!$model->setOptimisticRaw(payment_status = ?,[1]))->save())
throws new Exception(订单已付过款了);
如果同一对象小涉及到多次更新,则可以清除锁条件
1
$ord->clearOptimistic();
推荐学习:《laravel视频教程》
以上就是Laravel Eloquent模型中乐观锁的实现的详细内容,更多请关注php中文网其它相关文章!