最近在看Elasticsearch時看到了併發控制,由此看到了新的併發控制方式。不得不說Elasticsearch相較於關係型數據庫就是兩種理論創建的數據存儲體系,固然它們在併發控制上也相差甚遠,各有千秋。
數據庫
說到併發就不得不提一下串行,所謂串行就是數據庫操做事物按照特定的順序從上到下執行,在串行操做某個數據表的某個字段的值時寫入和讀取都很好理解,且不會發生異常。可是每每線上數據操做會發生各類異常,由於線上數據庫對用戶來講不多是串行訪問的,每每是併發訪問。就會產生如寫入併發形成的覆蓋現象,讀寫併發形成的髒讀現象等。下面簡單介紹一下這些異常造成的緣由。併發
A獲取字段X的值爲3將它減1而後寫入數據庫X爲2,當B在A寫入以前同時獲取X的值爲3將它減1而後寫入數據庫X爲2。
能夠看到上面X通過兩次減1操做,可是它的值只減了1,由於B將A的操做覆蓋了。測試
若是X的值爲1,A想將X的值減1,若是X等於0則返回,當A將減1操做執行完成前,B一樣進行這個操做,B取到的X也等於1,而後執行減1操做,會是X的值變爲-1。線程
上面的例子說明了併發操做中存在衝突,須要一種機制來處理這種衝突。因而鎖的機制就應運而生來。鎖顧名思義就是將須要執行的數據鎖起來,從而讓他從併發變成串行。
設計
悲觀鎖對數據被修改持悲觀態度。即每次獲取數據的時候,都會擔憂數據被修改,因此每次獲取數據的時候都會進行加鎖,確保在本身使用的過程當中數據不會被別人修改,使用完成後進行數據解鎖。因爲數據進行加鎖,期間對該數據進行讀寫的其餘線程都會進行等待。
事務
在數據庫中,鎖被設計爲兩種模式,即共享鎖(讀鎖)和互斥鎖(寫鎖)。當一個事物得到共享鎖以後,它只能進行讀操做;當一個事物獲取一行數據當互斥鎖時,就能夠對該行數據進行讀和寫操做。
多個事物能夠同時獲取同一行數據的共享鎖,但互斥鎖同一時間只能被一個事物獲取。沒有得到鎖但事物將處於等待狀態。
ast
兩階段鎖協議是一種可以保證事物可串行化但協議,它將事物的獲取鎖和釋放鎖分紅增加和縮減兩個不一樣的階段。在增加階段,一個事物能夠得到鎖可是不能釋放鎖;而在縮減階段事物只能夠釋放鎖,不能獲取新的鎖。變量
樂觀鎖並非真正的鎖,而是一種併發控制的思想。它能夠基於各類協議來實現這種併發控制。不一樣的事物按照鎖協議同一數據項依次執行,由於後面執行的事務想要獲取的數據已經被前面的事務加鎖,只能等待鎖的釋放。
時間戳
每一個事務都有一個全局惟一且隨時間遞增的時間戳。每一項數據有兩個時間戳分別是讀時間戳和寫時間戳,分別表明事務的開始和結束。這個協議使不管讀操做仍是寫操做都須要比較讀寫時間戳,若是小於當前值(最後一次操做都時間戳)就會拒絕,而後回滾,而後數據庫給這個事務一個新的時間戳從新執行。
數據
這個協議根據事務的只讀或者更新將全部事務的執行分爲兩到三個階段。
在讀階段,數據庫會執行事務中的所有讀操做和寫操做,並將因此寫後的值村潤臨時變量中,並不會真正更新數據庫的內容;而後進入下一階段,數據庫會檢測當前改動是否合法,便是否有其餘事務在讀階段更新了數據,若是經過測試就直接寫入數據庫,不然就拒絕執行。
多版本併發控制意味着更新數據時不覆蓋原數據,而是在數據庫中保留多個版本,根據須要使用某個版本。它本質上跟上面的不衝突,屬於兩種解決方案,它並不能解決衝突而是將衝突分割開。