樂觀鎖和悲觀鎖

樂觀鎖

      每次獲取數據的時候,都不會擔憂數據被修改,因此每次獲取數據的時候都不會進行加鎖,可是在更新數據的時候須要判斷該數據是否被別人修改過。若是數據被其餘線程修改,則不進行數據更新,若是數據沒有被其餘線程修改,則進行數據更新。因爲數據沒有進行加鎖,期間該數據能夠被其餘線程進行讀寫操做。通常使用version方式和CAS操做方式。數據庫

Version方式:spa

        通常是在數據表中加上一個數據版本號version字段,表示數據被修改的次數,當數據被修改時,version值會加一。當線程A要更新數據值時,在讀取數據的同時也會讀取version值,在提交更新時,若剛纔讀取到的version值爲當前數據庫中的version值相等時才更新,不然重試更新操做,直到更新成功。線程

核心SQL代碼:update table set x=x+1, version=version+where id=#{id} and version=#{version};

 CAS操做方式:code

        即compare and swap 或者 compare and set,涉及到三個操做數,數據所在的內存值,預期值,新值。當須要更新時,判斷當前內存值與以前取到的值是否相等,若相等,則用新值更新,若失敗則重試,通常狀況下是一個自旋操做,即不斷的重試。內存

樂觀鎖使用場景io

      比較適合讀取操做比較頻繁的場景,若是出現大量的寫入操做,數據發生衝突的可能性就會增大,爲了保證數據的一致性,應用層須要不斷的從新獲取數據,這樣會增長大量的查詢操做,下降了系統的吞吐量。table

悲觀鎖date

        每次獲取數據的時候,都會擔憂數據被修改,因此每次獲取數據的時候都會進行加鎖,確保在本身使用的過程當中數據不會被別人修改,使用完成後進行數據解鎖。因爲數據進行加鎖,期間對該數據進行讀寫的其餘線程都會進行等待。在Java中,synchronized的思想也是悲觀鎖數據

悲觀鎖使用場景查詢

       比較適合寫入操做比較頻繁的場景,若是出現大量的讀取操做,每次讀取的時候都會進行加鎖,這樣會增長大量的鎖的開銷,下降了系統的吞吐量。

相關文章
相關標籤/搜索