數據建模實戰之基于全局鎖實現悲觀鎖并發控制

1、悲觀鎖的簡要說明

基于version的樂觀鎖并發控制

在數據建模,結合文件系統建模的這個案例,把悲觀鎖的并發控制,3種鎖粒度,都給大家仔細講解一下

最粗的一個粒度,全局鎖

/workspace/projects/helloworld

如果多個線程,都過來,要并發地給/workspace/projects/helloworld下的README.txt修改文件名

實際上要進行并發的控制,避免出現多線程的并發安全問題,比如多個線程修改,純并發,先執行的修改操作被后執行的修改操作給覆蓋了

get current version

帶著這個current version去執行修改,如果一旦發現數據已經被別人給修改了,version號跟之前自己獲取的已經不一樣了; 那么必須重新獲取新的version號再次嘗試修改

上來就嘗試給這條數據加個鎖,然后呢,此時就只有你能執行各種各樣的操作了,其他人不能執行操作

第一種鎖:全局鎖,直接鎖掉整個fs index

2、全局鎖的上鎖實驗

PUT /fs/lock/global/_create
{}

fs: 你要上鎖的那個index
lock: 就是你指定的一個對這個index上全局鎖的一個type
global: 就是你上的全局鎖對應的這個doc的id
_create:強制必須是創建,如果/fs/lock/global這個doc已經存在,那么創建失敗,報錯

利用了doc來進行上鎖

/fs/lock/global /index/type/id --> doc

{
  "_index": "fs",
  "_type": "lock",
  "_id": "global",
  "_version": 1,
  "result": "created",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "created": true
}

另外一個線程同時嘗試上鎖

PUT /fs/lock/global/_create
{}
{
  "error": {
    "root_cause": [
      {
        "type": "version_conflict_engine_exception",
        "reason": "[lock][global]: version conflict, document already exists (current version [1])",
        "index_uuid": "IYbj0OLGQHmMUpLfbhD4Hw",
        "shard": "2",
        "index": "fs"
      }
    ],
    "type": "version_conflict_engine_exception",
    "reason": "[lock][global]: version conflict, document already exists (current version [1])",
    "index_uuid": "IYbj0OLGQHmMUpLfbhD4Hw",
    "shard": "2",
    "index": "fs"
  },
  "status": 409
}

如果失敗,就再次重復嘗試上鎖

執行各種操作。。。

POST /fs/file/1/_update
{
  "doc": {
    "name": "README1.txt"
  }
}
{
  "_index": "fs",
  "_type": "file",
  "_id": "1",
  "_version": 2,
  "result": "updated",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  }
}
DELETE /fs/lock/global
{
  "found": true,
  "_index": "fs",
  "_type": "lock",
  "_id": "global",
  "_version": 2,
  "result": "deleted",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  }
}

另外一個線程,因為之前發現上鎖失敗,反復嘗試重新上鎖,終于上鎖成功了,因為之前獲取到全局鎖的那個線程已經delete /fs/lock/global全局鎖了

PUT /fs/lock/global/_create
{}
{
  "_index": "fs",
  "_type": "lock",
  "_id": "global",
  "_version": 3,
  "result": "created",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "created": true
}
POST /fs/file/1/_update 
{
  "doc": {
    "name": "README.txt"
  }
}
{
  "_index": "fs",
  "_type": "file",
  "_id": "1",
  "_version": 3,
  "result": "updated",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  }
}
DELETE /fs/lock/global

3、全局鎖的優點和缺點

優點:操作非常簡單,非常容易使用,成本低
缺點:你直接就把整個index給上鎖了,這個時候對index中所有的doc的操作,都會被block住,導致整個系統的并發能力很低

上鎖解鎖的操作不是頻繁,然后每次上鎖之后,執行的操作的耗時不會太長,用這種方式,方便

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容