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

5765809發表於2024-10-01

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

(1)先構造一條資料出來

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

(2)模擬兩個客戶端,都獲取到了同一條資料

GET test_index/test_type/7

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

(3)其中一個客戶端,先更新了一下這個資料

同時帶上資料的版本號,確保說,es中的資料的版本號,跟客戶端中的資料的版本號是相同的,才能修改

PUT /test_index/test_type/7?version=1
{
"test_field": "test client 1"
}

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

(4)另外一個客戶端,嘗試基於version=1的資料去進行修改,同樣帶上version版本號,進行樂觀鎖的併發控制

PUT /test_index/test_type/7?version=1
{
"test_field": "test client 2"
}

{
"error": {
"root_cause": [
{
"type": "version_conflict_engine_exception",
"reason": "[test_type][7]: version conflict, current version [2] is different than the one provided [1]",
"index_uuid": "6m0G7yx7R1KECWWGnfH1sw",
"shard": "3",
"index": "test_index"
}
],
"type": "version_conflict_engine_exception",
"reason": "[test_type][7]: version conflict, current version [2] is different than the one provided [1]",
"index_uuid": "6m0G7yx7R1KECWWGnfH1sw",
"shard": "3",
"index": "test_index"
},
"status": 409
}

(5)在樂觀鎖成功阻止併發問題之後,嘗試正確的完成更新

GET /test_index/test_type/7

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

基於最新的資料和版本號,去進行修改,修改後,帶上最新的版本號,可能這個步驟會需要反覆執行好幾次,才能成功,特別是在多執行緒併發更新同一條資料很頻繁的情況下

PUT /test_index/test_type/7?version=2
{
"test_field": "test client 2"
}

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

相關文章