Laravel Eloquent模型中乐观锁的实现
发布时间 - 2023-04-21 00:00:00 点击率:次本篇文章给大家带来了关于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
# php
# sql
# 父类
# 对象
# 字段名
# 感兴趣
# 也很
# 带来了
# 给大家
# 有必要
# 涉及到
# 则可
# 相关知识
# 目录下
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?
如何制作一个表白网站视频,关于勇敢表白的小标题?
Laravel API资源(Resource)怎么用_格式化Laravel API响应的最佳实践
合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?
青岛网站建设如何选择本地服务器?
Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载
Laravel如何实现API版本控制_Laravel版本化API设计方案
网站制作报价单模板图片,小松挖机官方网站报价?
DeepSeek是免费使用的吗 DeepSeek收费模式与Pro版本功能详解
Laravel如何实现用户注册和登录?(Auth脚手架指南)
Laravel全局作用域是什么_Laravel Eloquent Global Scopes应用指南
高端网站建设与定制开发一站式解决方案 中企动力
详解Oracle修改字段类型方法总结
1688铺货到淘宝怎么操作 1688一键铺货到自己店铺详细步骤
公司网站制作需要多少钱,找人做公司网站需要多少钱?
简单实现jsp分页
Laravel策略(Policy)如何控制权限_Laravel Gates与Policies实现用户授权
详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)
网站制作大概多少钱一个,做一个平台网站大概多少钱?
Laravel怎么实现软删除SoftDeletes_Laravel模型回收站功能与数据恢复【步骤】
Laravel路由Route怎么设置_Laravel基础路由定义与参数传递规则【详解】
bing浏览器学术搜索入口_bing学术文献检索地址
Laravel如何生成URL和重定向?(路由助手函数)
Laravel项目结构怎么组织_大型Laravel应用的最佳目录结构实践
微博html5版本怎么弄发语音微博_语音录制入口及时长限制操作【教程】
Linux后台任务运行方法_nohup与&使用技巧【技巧】
北京网页设计制作网站有哪些,继续教育自动播放怎么设置?
手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?
济南网站建设制作公司,室内设计网站一般都有哪些功能?
python中快速进行多个字符替换的方法小结
如何快速查询网址的建站时间与历史轨迹?
bootstrap日历插件datetimepicker使用方法
jquery插件bootstrapValidator表单验证详解
如何在Ubuntu系统下快速搭建WordPress个人网站?
Java类加载基本过程详细介绍
微博html5版本怎么弄发超话_超话进入入口及发帖格式要求【教程】
Android利用动画实现背景逐渐变暗
C#如何调用原生C++ COM对象详解
Win11怎么关闭资讯和兴趣_Windows11任务栏设置隐藏小组件
iOS发送验证码倒计时应用
Laravel如何实现API资源集合?(Resource Collection教程)
如何快速上传自定义模板至建站之星?
如何快速生成高效建站系统源代码?
Laravel Admin后台管理框架推荐_Laravel快速开发后台工具
如何快速搭建FTP站点实现文件共享?
详解Nginx + Tomcat 反向代理 负载均衡 集群 部署指南
Laravel怎么使用Intervention Image库处理图片上传和缩放
如何为不同团队 ID 动态生成多个“认领值班”按钮
Laravel中Service Container是做什么的_Laravel服务容器与依赖注入核心概念解析
如何解决hover在ie6中的兼容性问题


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;
}}