广告
返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >Yii框架实现乐观锁与悲观锁流程详解
  • 307
分享到

Yii框架实现乐观锁与悲观锁流程详解

Yii乐观锁与悲观锁Yii悲观锁Yii乐观锁 2022-11-13 19:11:22 307人浏览 八月长安
摘要

目录一、在Yii中实现乐观锁1、在yii中实现乐观锁步骤2、Yii中实现乐观锁3、实现乐观锁二、在Yii中实现悲观锁1、在yii中实现悲观锁的步骤2、yii中悲观锁实现一、在Yii中

一、在Yii中实现乐观锁

乐观锁(optimistic locking)表现出大胆、务实的态度。使用乐观锁的前提是, 实际应用当中,发生冲突的概率比较低。他的设计和实现直接而简洁。 目前WEB应用中,乐观锁的使用占有绝对优势。因此在Yii为ActiveReocrd乐观锁支持

1、在yii中实现乐观锁步骤

1、给需要加锁的表添加一个字段,用于表示版本号,这里我一般选手version字段作为版本号字段,注意,如果你需要加锁的表已经生成Model了,那么对应表的Model要将你添加的版本号字段(version)信息加入Model

2、在更新表中字段时,使用 try ... catch 看看是否能捕获一个 yii\db\StaleObjectException 异常,如果捕捉到yii\db\StaleObjectException 异常,说明在本次修改这个记录的过程中, 该记录已经被修改过了,作出相应提示

2、Yii中实现乐观锁

1、在yii中声明指定字段为版本号

版本号是实现乐观锁的根本所在。所以第一步,我们要告诉Yii,哪个字段是版本号字段,声明版本号的方法由yii\db\BaseActiveRecord(vendor/yiisoft/yii2/db/BaseActiveRecord)中的optimisticLock方法负责

public function optimisticLock()
{
    return null;
}

这个方法返回 null ,表示不使用乐观锁,如果我们需要使用乐观锁的话,我们需要在我们的需要加锁的表的Model中重载optimisticLock方法

public function optimisticLock()
{
    return 'version';
}

如上说明当前的ActiveRecord中,有一个 version 字段,可以为乐观锁所用

3、实现乐观锁

我们在Model中设置了版本号后,这时候我们的更新和删除都是乐观锁操作了,与正常操作数据库的方式一致

try {
    $crowd = Crowd::findOne(['crowd_id' => 12]);
    $crowd->status = 1;
    $crowd->save();
} catch (\Exception $e) {
    return false;
}

在更新过程中,我们会调用到 yii\db\BaseActiveRecord::updateInternal()方法,此方法里面就具有处理乐观锁的代码

protected function updateInternal($attributes = null)
{
    if (!$this->beforeSave(false)) {
      return false;
    }
    // 获取等下要更新的字段及新的字段值
    $values = $this->getDirtyAttributes($attributes);
    if (empty($values)) {
      $this->afterSave(false, $values);
      return 0;
    }
    // 把原来ActiveRecord的主键作为等下更新记录的条件,也就是说,等下更新的,最多只有1个记录。
    $condition = $this->getOldPrimaryKey(true);
    // 获取版本号字段的字段名,比如 version
    $lock = $this->optimisticLock();
    // 如果 optimisticLock() 返回的是 null,那么,不启用乐观锁。
    if ($lock !== null) {
    // 这里的 $this->$lock ,就是 $this->version 的意思; 这里把 version+1 作为要更新的字段之一。
      $values[$lock] = $this->$lock + 1;
      // 这里把旧的版本号作为更新的另一个条件
      $condition[$lock] = $this->$lock;
    }
    $rows = static::updateAll($values, $condition);
// 如果已经启用了乐观锁,但是却没有完成更新,或者更新的记录数为0;
  // 那就说明是由于 version 不匹配,记录被修改过了,于是抛出异常。
    if ($lock !== null && !$rows) {
      throw new StaleObjectException('The object being updated is outdated.');
    }
    if (isset($values[$lock])) {
      $this->$lock = $values[$lock];
    }
    $changedAttributes = [];
    foreach ($values as $name => $value) {
      $changedAttributes[$name] = isset($this->_oldAttributes[$name]) ? $this->_oldAttributes[$name] : null;
      $this->_oldAttributes[$name] = $value;
    }
    $this->afterSave(false, $changedAttributes);
    return $rows;
}

在删除过程中,我们会调用到 yii\db\BaseActiveRecord::delete()方法,此方法里面就具有处理乐观锁的代码

public function delete()
    {
        $result = false;
        if ($this->beforeDelete()) {
            // 删除的sql语句中,WHERE部分是主键
            $condition = $this->getOldPrimaryKey(true);
            // 获取版本号字段的字段名,比如 version
            $lock = $this->optimisticLock();
            // 如果启用乐观锁,那么WHERE部分再加一个条件,版本号
            if ($lock !== null) {
                $condition[$lock] = $this->$lock;
            }
            $result = static::deleteAll($condition);
            if ($lock !== null && !$result) {
                throw new StaleObjectException('The object being deleted is outdated.');
            }
            $this->_oldAttributes = null;
            $this->afterDelete();
        }
        return $result;
    }

如上我们就知道了,在yii中已经有了乐观锁相关的代码了,我们只需要在Model中设置一个版本号字段即可

二、在Yii中实现悲观锁

正如其名字,悲观锁(pessimistic locking)体现了一种谨慎的处事态度

1、在yii中实现悲观锁的步骤

1、在对任意记录进行修改前,先尝试为该记录加上锁

2、如果加锁失败,说明该记录正在被修改,那么当前查询可能要等待或者抛出异常

3、如果成功加锁,那么就可以对记录做修改,事务完成后就会解锁了

2、yii中悲观锁实现

使用select.....for update实现悲观锁,简单示例如下:

$transaction = Yii::$app->db->beginTransaction();
try{
    //查询id为12的这条数据并且锁定
    $sql = "select * from ubo_crowd where crowd_id = 12 for update";
    $crowd = Yii::$app->db->createCommand($sql)->queryOne();
    //更新数据
    $crowd1 = Crowd::findOne(['crowd_id' => $crowd['crowd_id']]);
    $crowd1->sort += 1;
    if($crowd1->save()){
        $transaction->commit();
    }
}catch(Exception $e){
    $transaction->rollBack();
}

到此这篇关于Yii框架实现乐观锁与悲观锁流程详解的文章就介绍到这了,更多相关Yii乐观锁与悲观锁内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Yii框架实现乐观锁与悲观锁流程详解

本文链接: https://www.lsjlt.com/news/170630.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Yii框架实现乐观锁与悲观锁流程详解
    目录一、在Yii中实现乐观锁1、在yii中实现乐观锁步骤2、Yii中实现乐观锁3、实现乐观锁二、在Yii中实现悲观锁1、在yii中实现悲观锁的步骤2、yii中悲观锁实现一、在Yii中...
    99+
    2022-11-13
    Yii乐观锁与悲观锁 Yii悲观锁 Yii乐观锁
  • 详解Java中的悲观锁与乐观锁
    目录一、悲观锁二、乐观锁三、CAS四、AtomicXXX五、CAS中的ABA问题六、ABA问题解决方案七、使用CAS会引起的问题八、Synchronized锁优化九、偏向锁十、轻量级...
    99+
    2022-11-12
  • MySQL悲观锁与乐观锁如何实现
    这篇文章主要为大家展示了“MySQL悲观锁与乐观锁如何实现”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“MySQL悲观锁与乐观锁如何实现”这篇文章吧。前言悲观锁和乐观锁是用来解决并发问题的两种思...
    99+
    2023-06-25
  • MySQL悲观锁与乐观锁的实现方案
    目录前言实战 1、无锁2、悲观锁3、乐观锁总结前言 悲观锁和乐观锁是用来解决并发问题的两种思想,在不同的平台有着各自的实现。例如在Java中,synchronized就可以认为是悲观...
    99+
    2022-11-12
  • 悲观锁与乐观锁怎么利用Hibernate实现
    这篇文章将为大家详细讲解有关悲观锁与乐观锁怎么利用Hibernate实现,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。四种隔离机制不要忘记:(1,2,4,8)1.read-uncommitt...
    99+
    2023-05-31
    hibernate 悲观锁 乐观锁
  • MyBatisPlus+SpringBoot实现乐观锁功能详细流程
    目录一、商城数据不一致的场景二、演示这一过程1、数据库中增加商品表2、创建实体类3、创建Mapper4、进行测试三、乐观锁方案四、乐观锁实现流程1、修改实体类2、添加乐观锁插件3、优...
    99+
    2023-03-24
    springboot乐观锁 mybatisplus乐观锁 java 乐观锁
  • mybatis plus乐观锁及实现详解
    目录乐观锁一、什么是乐观锁二、MP来实现乐观锁1.在实体类里增加对于的字段,并且加上自动填充(你也可以每次手动填充)2. 配置插件3.测试乐观锁乐观锁 乐观锁”这个词以前...
    99+
    2022-11-13
  • 详解JAVA如何实现乐观锁以及CAS机制
    目录前言问题引入悲观锁解决乐观锁解决乐观锁改进CAS机制总结前言 生活中我们看待一个事物总有不同的态度,比如半瓶水,悲观的人会觉得只有半瓶水了,而乐观的人则会认为还有半瓶水呢。很多技...
    99+
    2022-12-08
    JAVA乐观锁 CAS机制 JAVA乐观锁 JAVA CAS
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作