18 樂觀鎖與悲觀鎖的區別

樂觀鎖和悲觀鎖都是用於解決併發場景下的數據競爭問題,但是卻是2種不同的思想。他們的使用非常的廣泛,也不侷限於某種語言或者數據庫。

樂觀鎖的概念: 樂觀鎖指的是在操作數據的時候非常的樂觀,樂觀的認爲被人不會同時修改數據,因此樂觀鎖默認不會上鎖的,只有在執行更新的時候纔會去判斷在此期間別人是否修改了數據,如果別人修改了數據則放棄操作,否則執行操作。,
衝突比較少的時候,使用樂觀鎖,由於樂觀鎖的不上鎖特性,所有在性能方面要比悲觀鎖好,比較適合在db的讀大於寫的業務場景。
悲觀鎖的概念:悲觀鎖指的是在操作數據庫的時候比較悲觀,悲觀的認爲別人一定會同時修改數據,因此悲觀鎖在操作數據庫的時候是直接把數據上鎖的,直到操作完成後纔會釋放鎖,在上鎖期間其他人不能操作數據。
衝突比較多的時候,使用悲觀鎖對於每一次數據修改都要上鎖,如果在db讀取需要比較大的情況下有線程在執行數據修改操作會導致讀操作全部被掛載起來,等修改線程釋放了鎖才能讀取到數據,體驗感差。所以 比較適合用在db寫大於讀的時候

讀取頻繁使用樂觀鎖,寫入頻繁使用悲觀鎖。
樂觀鎖的實現方式:
樂觀鎖的實現方式主要有2種,一種是cas(Compare and Swap,比較並交換)機制,一種是版本號機制。
CAS機制:
CAS操作包括了三個操作數,分別是需要讀取的內存位置(V)、進行比較的預期值(A)和擬寫入的新值(B),操作邏輯是,如果內存位置V的值等於預期值A,則將該位置更新爲新值B,否則不進行操作。另外,許多CAS操作都是自旋的,意思就是,如果操作不成功,就會一直重試,直到操作成功爲止。
版本號機制:
版本號機制的基本思路,是在數據中增加一個version字段用來表示該數據的版本號,每當數據被修改版本號就會加1。當某個線程查詢數據的時候,會將該數據的版本號一起讀取出來,之後在該線程需要更新該數據的時候,就將之前讀取的版本號與當前版本號進行比較,如果一致,則執行操作,如果不一致,則放棄操作
悲觀鎖的實現方式:
悲觀鎖的實現方式也就是加鎖,加鎖既可以在代碼層面(比如java中的關鍵字synchronized關鍵字),也可以在數據庫層面(比如MySQL中的排它鎖)。
樂觀鎖和悲觀鎖並沒有優劣之分,他們有各自的適合場景。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章