https://www.elastic.co/guide/cn/elasticsearch/guide/current/optimistic-concurrency-control.html
當我們之前討論 index , GET 和 delete 請求時,我們指出每個文檔都有一個 _version (版本)號,當文檔被修改時版本號遞增。 Elasticsearch 使用這個 _version 號來確保變更以正確順序得到執行。如果舊版本的文檔在新版本之后到達,它可以被簡單的忽略。
我們可以利用 _version 號來確保 應用中相互沖突的變更不會導致數據丟失。我們通過指定想要修改文檔的 version 號來達到這個目的。 如果該版本不是當前版本號,我們的請求將會失敗。
讓我們創建一個新的博客文章:
PUT /website/blog/1/_create
{
"title": "My first blog entry",
"text": "Just trying this out..."
}
現在,當我們嘗試通過重建文檔的索引來保存修改,我們指定 version 為我們的修改會被應用的版本:
PUT /website/blog/1?version=1
{
"title": "My first blog entry",
"text": "Starting to get the hang of this..."
}
我們想這個在我們索引中的文檔只有現在的 _version 為 1 時,本次更新才能成功。
此請求成功,並且響應體告訴我們 _version 已經遞增到 2。
然而,如果我們重新運行相同的索引請求,仍然指定 version=1 , Elasticsearch 返回 409 ConflictHTTP 響應碼,和一個如下所示的響應體:
{
"error": {
"root_cause": [
{
"type": "version_conflict_engine_exception",
"reason": "[blog][1]: version conflict, current [2], provided [1]",
"index": "website",
"shard": "3"
}
],
"type": "version_conflict_engine_exception",
"reason": "[blog][1]: version conflict, current [2], provided [1]",
"index": "website",
"shard": "3"
},
"status": 409
}
這告訴我們在 Elasticsearch 中這個文檔的當前 _version 號是 2 ,但我們指定的更新版本號為 1 。
我們現在怎么做取決於我們的應用需求。我們可以告訴用戶說其他人已經修改了文檔,並且在再次保存之前檢查這些修改內容。 或者,在之前的商品 stock_count 場景,我們可以獲取到最新的文檔並嘗試重新應用這些修改。
所有文檔的更新或刪除 API,都可以接受 version 參數,這允許你在代碼中使用樂觀的並發控制,這是一種明智的做法。