1. 程式人生 > >elastic 部分更新 retry_on_conflict 和 數據庫寫鎖 詳細比對

elastic 部分更新 retry_on_conflict 和 數據庫寫鎖 詳細比對

and last conf 區分 文檔 刪除 階段 不同 重建

1 數據庫的 update 在修改這條數據的的過程中(這個過程指的是 數據庫執行update 到 事務提交的過程中 )為這條數據加上 寫鎖,阻止 別的事務 對鎖定數據的修改,請求後一個修改事務的線程阻塞,直到前一個事務的完成,所以針對這條數據的 2 個修改 是一個一個來的。所以 數據庫的 update t1 set a = a+1; 這樣的操作 不會導致 a數據的 丟失,因為前一個事務 執行的時候回阻塞後一個事務提交數據。 但是 如果先查詢出a=1, 然後 a = 1(這個1 是查詢到的 a)+1 ;這樣的操作會 丟失 a ,因為 a 兩個事務查詢的a 可能 會被修改了。

2, es 的 全部修改,如果沒有帶上 version的 時候,直接替換原來的 文檔,沒有查詢的過程。多線程操作,不區分執行的先後順序。 但是帶上version的時候 version 表示先後順序。先執行成功的為主,後來的不合法被舍棄(拋出異常)。

3, es 部分修改的時候,修改請求到達 es 的 時候,es會在內部查詢 一下原理的文檔,然後執行 ,部分更新,註意一下,這時候 是 es 並不阻止 別的線程修改 這條數據,可能這個es 內部的查詢 同是有多個( 這個階段叫做 retrieve ),檢索完成 記錄一下 這是的     version,  和傳過來的新的數據一起生成新的文檔,然後把舊的文檔改成假刪除(這個過程叫做 reindex),這時候會修改 set version=version and version = version,如果另一個 線程做著同樣的操作並且慢了 一點點,重建 索引這步 就會出異常。這時候 es會 重 復檢索和 重構索引的過程 知道 正常完成 或者 重試次數大於 retry_on_conflict 拋出異常。

  es 會吧 原理的就文檔

總結:數據庫 拒絕 第二個事務來修改 已經被修改但是未被提交的數據(事務未提交)。 es 的全更新 不會有自動檢索 的過程,直接替換,可以通過version 控制並發。部分更新有自動檢索的過程 ,並發修改沖突會重新檢索,帶上version然後重新新構建索引

   重試 retry_on_conflict 次後會拋出異常,並且 也可以通過 version 控制(retry_on_conflict 默認0 次 相當於 自動帶上了version,但是不完成等價 , 因為 version 讀的 時機 不同,有些情況可能 不同的結果,主要肯寫法 和 業務 情景 比如 a = a+1 就沒影響,但是 a = 1+1 就有影響,可以細細體會 一下,挺有意思的 )。

elastic 部分更新 retry_on_conflict 和 數據庫寫鎖 詳細比對