久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

深入理解Yii2.0樂觀鎖與悲觀鎖的原理與使用

這篇文章主要介紹了深入理解Yii2.0樂觀鎖與悲觀鎖的原理與使用,具有一定的參考價值,感興趣的小伙伴們可以參考一下。

本文介紹了深入理解Yii2.0樂觀鎖與悲觀鎖的原理與使用,分享給大家,具體如下:

Web應用往往面臨多用戶環境,這種情況下的并發寫入控制, 幾乎成為每個開發人員都必須掌握的一項技能。

在并發環境下,有可能會出現臟讀(Dirty Read)、不可重復讀(Unrepeatable Read)、 幻讀(Phantom Read)、更新丟失(Lost update)等情況。具體的表現可以自行搜索。

為了應對這些問題,主流數據庫都提供了鎖機制,并引入了事務隔離級別的概念。 這里我們都不作解釋了,拿這些關鍵詞一搜,網上大把大把的。

但是,就于具體開發過程而言,一般分為悲觀鎖和樂觀鎖兩種方式來解決并發沖突問題。

樂觀鎖

樂觀鎖(optimistic locking)表現出大膽、務實的態度。使用樂觀鎖的前提是, 實際應用當中,發生沖突的概率比較低。他的設計和實現直接而簡潔。 目前Web應用中,樂觀鎖的使用占有絕對優勢。

因此,Yii也為ActiveReocrd提供了樂觀鎖支持。

根據Yii的官方文檔,使用樂觀鎖,總共分4步:

  • 為需要加鎖的表增加一個字段,用于表示版本號。 當然相應的Model也要為該字段的加入,作出適當調整。比如, rules() 中要加入該字段。
  • 重載 yii\db\ActiveRecord::optimisticLock() 方法,返回上一步中的字段名。
  • 在記錄的修改頁面表單中,加入一個 <input type="hidden"> 用于暫存讀取時的記錄的版本號。
  • 在保存代碼的地方,使用 try ... catch 看看是否能捕獲一個 yii\db\StaleObjectException 異常。如果是,說明在本次修改這個記錄的過程中, 該記錄已經被修改過了。簡單應對的話,可以作出相應提示。智能點的話, 可以合并不沖突的修改,或者顯示一個diff頁面。

從本質上來講,樂觀鎖并沒有像悲觀鎖那樣使用數據庫的鎖機制。 樂觀鎖通過在表中增加一個計數字段,來表示當前記錄被修改的次數(版本號)。

然后在更新、刪除前通過比對版本號來實現樂觀鎖。

聲明版本號字段

版本號是實現樂觀鎖的根本所在。所以第一步,我們要告訴Yii,哪個字段是版本號字段。 這個由 yii\db\BaseActiveRecord 負責:

public function optimisticLock()
{
  return null;
}

這個方法返回 null ,表示不使用樂觀鎖。那么我們的Model中,要對此進行重載。 返回一個字符串,表示我們用于標識版本號的字段。比如可以這樣:

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

說明當前的ActiveRecord中,有一個 ver 字段,可以為樂觀鎖所用。 那么Yii具體是如何借助這個 ver 字段實現樂觀鎖的呢?

更新過程

具體來講,使用樂觀鎖之后的更新過程,就是這么一個流程:

  1. 讀取要更新的記錄。
  2. 對記錄按照用戶的意愿進行修改。當然,這個時候不會修改 ver 字段。 這個字段對用戶是沒意義的。
  3. 在保存記錄前,再次讀取這個記錄的 ver 字段,與之前讀取的值進行比對。
  4. 如果 ver 不同,說明在用戶修改過程中,這個記錄被別人改動過了。那么, 我們要給出提示。
  5. 如果 ver 相同,說明這個記錄未被修改過。那么,對 ver +1, 并保存這個記錄。這樣子就完成了記錄的更新。同時,該記錄的版本號也加了1。

由于ActiveRecord的更新過程最終都需要調用 yii\db\BaseActiveRecord::updateInteranl() ,理所當然地,處理樂觀鎖的代碼, 也就隱藏在這個方法中:

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

  // 獲取版本號字段的字段名,比如 ver
  $lock = $this->optimisticLock();

  // 如果 optimisticLock() 返回的是 null,那么,不啟用樂觀鎖。
  if ($lock !== null) {
    // 這里的 $this->$lock ,就是 $this->ver 的意思;
    // 這里把 ver+1 作為要更新的字段之一。
    $values[$lock] = $this->$lock + 1;

    // 這里把舊的版本號作為更新的另一個條件
    $condition[$lock] = $this->$lock;
  }
  $rows = $this->updateAll($values, $condition);

  // 如果已經啟用了樂觀鎖,但是卻沒有完成更新,或者更新的記錄數為0;
  // 那就說明是由于 ver 不匹配,記錄被修改過了,于是拋出異常。
  if ($lock !== null && !$rows) {
    throw new StaleObjectException('The object being updated is outdated.');
  }
  $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;
}

【網站聲明】本站除付費源碼經過測試外,其他素材未做測試,不保證完整性,網站上部分源碼僅限學習交流,請勿用于商業用途。如損害你的權益請聯系客服QQ:2655101040 給予處理,謝謝支持。

相關文檔推薦

本篇文章主要介紹了yii2組件之下拉框帶搜索功能的示例代碼(yii-select2),具有一定的參考價值,有興趣的可以了解一下
本篇文章主要主要介紹了yii2中使用webuploader實現圖片上傳的實戰項目,具有一定的參考價值,有興趣的同學可以了解一下
本篇文章主要介紹了淺談Yii2 樂觀鎖與悲觀鎖原理,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
下面小編就為大家帶來一篇修改yii2.0用戶登錄使用的user表為其它的表實現方法(推薦)。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
因為某種原因,不想用yii自帶的user表,想用自己建的admin數據庫表,怎么修改呢?下面小編給大家介紹下修改yii2.0自帶的user表為其它的表的方法,一起看看吧
本篇文章主要介紹了Yii2第三方類庫插件Imagine的安裝和使用,具有一定的參考價值,感興趣的小伙伴們可以參考一下
主站蜘蛛池模板: 一级女毛片| 在线观看你懂的网站 | 久久婷婷色 | 亚洲成人综合社区 | 久久精彩视频 | 日韩成人在线电影 | 久久精品色欧美aⅴ一区二区 | 一级久久久久久 | www.婷婷 | 欧产日产国产精品国产 | 久久成人高清视频 | 女人av | 亚洲精品中文字幕在线观看 | heyzo在线| 亚洲在线高清 | 天天曰夜夜 | 国产精品久久久免费 | 超碰男人天堂 | 日本一区二区电影 | 国产视频三级 | 国产精品一区二区久久 | 岛国精品 | 午夜精品久久久久久久久久久久 | 亚洲成人精品 | 爱爱爱av | 午夜久久久 | 国产精品免费视频一区 | 影音先锋亚洲资源 | 成人精品一区二区三区中文字幕 | 91精品久久 | 日韩和的一区二在线 | 亚洲精品一区二区久 | 久久不卡 | 午夜精品久久久 | 国产精品视频久久 | 日本久久精品视频 | 爱草视频 | 91看片在线观看 | 亚洲精品视频免费观看 | 国产精品久久久久久久免费大片 | 成人在线电影在线观看 |