Laravel Eloquent模型中乐观锁的实现

来源:undefined 2025-01-04 00:18:55 1063

本篇文章给大家带来了关于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中文网其它相关文章!

最新文章