elasticsearch實現樂觀鎖

elasticsearch的寫操做是原子性的,能夠經過以下兩種方式實現es寫操做的樂觀鎖。html

基於_version

version_type在elasticsearch6.x被移除,故該方法不適用於6.x版本,詳見www.elastic.co/guide/en/el…git

PUT /user/user_type/1
{
  "name": "tom",
  "age": 18,
  "doc_version": 1 // 自定義的文檔版本號,用於樂觀鎖
}
複製代碼

只更新低版本的記錄github

PUT /user/user_type/1?version=2&version_type=external_gt
{
  "name": "tom",
  "age": 18,
  "doc_version": 2
}
複製代碼

忽略版本號強制更新bash

PUT /user/user_type/1?version=3&version_type=force
{
  "name": "tom",
  "age": 18,
  "doc_version": 3
}
複製代碼

基於script

PUT /user/user_type/1
{
  "name": "tom",
  "age": 18,
  "doc_version": 1 
}
複製代碼

只更新es中doc_version版本低的記錄less

POST /user/user_type/1/_update
{
  "script": {
    "source": "if(params.doc_force == true || ctx._source.doc_version < params.doc_version){for(entry in params.entrySet()){if (entry.getKey() != 'ctx') ctx._source[entry.getKey()] = entry.getValue();}}else{ctx.op = 'none'}",
    "lang": "painless",
    "params": {
      "name": "tom",
      "age": 19,
      "doc_version": 19
    }
  }
}
複製代碼

忽略自定義版本號doc_version強制更新記錄elasticsearch

POST /user/user_type/1/_update
{
  "script": {
    "source": "if(params.doc_force == true || ctx._source.doc_version < params.doc_version){for(entry in params.entrySet()){if (entry.getKey() != 'ctx') ctx._source[entry.getKey()] = entry.getValue();}}else{ctx.op = 'none'}",
    "lang": "painless",
    "params": {
      "name": "tom",
      "age": 19,
      "doc_version": 19,
      "doc_force": true
    }
  }
}
複製代碼

注:讀取script中的params的值時,須要過濾掉params.ctx,緣由是es的painless腳本會自動向params中添加ctx,若是不過濾,則上述的更新語法會報以下錯誤:ide

{
  "error": {
    "root_cause": [
      {
        "type": "remote_transport_exception",
        "reason": "[0l2AYvx][127.0.0.1:9300][indices:data/write/update[s]]"
      }
    ],
    "type": "illegal_argument_exception",
    "reason": "Iterable object is self-referencing itself"
  },
  "status": 400
}
複製代碼

詳見github.com/elastic/ela…ui

相關文章
相關標籤/搜索