22_上機動手實戰演練基於external version進行樂觀鎖併發控制

5765809發表於2024-10-01

課程大綱

1、上機動手實戰演練基於external version進行樂觀鎖併發控制

external version

es提供了一個feature,就是說,你可以不用它提供的內部_version版本號來進行併發控制,可以基於你自己維護的一個版本號來進行併發控制。舉個列子,加入你的資料在mysql裡也有一份,然後你的應用系統本身就維護了一個版本號,無論是什麼自己生成的,程式控制的。這個時候,你進行樂觀鎖併發控制的時候,可能並不是想要用es內部的_version來進行控制,而是用你自己維護的那個version來進行控制。

?version=1
?version=1&version_type=external

version_type=external,唯一的區別在於,_version,只有當你提供的version與es中的_version一模一樣的時候,才可以進行修改,只要不一樣,就報錯;當version_type=external的時候,只有當你提供的version比es中的_version大的時候,才能完成修改

es,_version=1,?version=1,才能更新成功
es,_version=1,?version>1&version_type=external,才能成功,比如說?version=2&version_type=external

(1)先構造一條資料

PUT /test_index/test_type/8
{
"test_field": "test"
}

{
"_index": "test_index",
"_type": "test_type",
"_id": "8",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"created": true
}

(2)模擬兩個客戶端同時查詢到這條資料

GET /test_index/test_type/8

{
"_index": "test_index",
"_type": "test_type",
"_id": "8",
"_version": 1,
"found": true,
"_source": {
"test_field": "test"
}
}

(3)第一個客戶端先進行修改,此時客戶端程式是在自己的資料庫中獲取到了這條資料的最新版本號,比如說是2

PUT /test_index/test_type/8?version=2&version_type=external
{
"test_field": "test client 1"
}

{
"_index": "test_index",
"_type": "test_type",
"_id": "8",
"_version": 2,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"created": false
}

(4)模擬第二個客戶端,同時拿到了自己資料庫中維護的那個版本號,也是2,同時基於version=2發起了修改

PUT /test_index/test_type/8?version=2&version_type=external
{
"test_field": "test client 2"
}

{
"error": {
"root_cause": [
{
"type": "version_conflict_engine_exception",
"reason": "[test_type][8]: version conflict, current version [2] is higher or equal to the one provided [2]",
"index_uuid": "6m0G7yx7R1KECWWGnfH1sw",
"shard": "1",
"index": "test_index"
}
],
"type": "version_conflict_engine_exception",
"reason": "[test_type][8]: version conflict, current version [2] is higher or equal to the one provided [2]",
"index_uuid": "6m0G7yx7R1KECWWGnfH1sw",
"shard": "1",
"index": "test_index"
},
"status": 409
}

(5)在併發控制成功後,重新基於最新的版本號發起更新

GET /test_index/test_type/8

{
"_index": "test_index",
"_type": "test_type",
"_id": "8",
"_version": 2,
"found": true,
"_source": {
"test_field": "test client 1"
}
}

PUT /test_index/test_type/8?version=3&version_type=external
{
"test_field": "test client 2"
}

{
"_index": "test_index",
"_type": "test_type",
"_id": "8",
"_version": 3,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"created": false
}

相關文章