樂觀鎖的兩種實現方式

什麼場景下需要使用鎖?

在多節點部署或者多線程執行時,同一個時間可能有多個線程更新相同數據,產生衝突,這就是併發問題。這樣的情況下會出現以下問題:
更新丟失:一個事務更新數據後,被另一個更新數據的事務覆蓋。
髒讀:一個事務讀取另一個事物爲提交的數據,即爲髒讀。
其次還有幻讀。。
針對併發引入併發控制機制,即加鎖。
加鎖的目的是在同一個時間只有一個事務在更新數據,通過鎖獨佔數據的修改權。

鎖的實現方式

          1、悲觀鎖,前提是,一定會有併發搶佔資源,強行獨佔資源,在整個數據處理過程中,將數據處於鎖定狀態。
          2、樂觀鎖,前提是,不會發生併發搶佔資源,只有在提交操作的時候檢查是否違反數據完整性。只能防止髒讀後數據的提交,不能解決髒讀。
          當然,還有其他的鎖機制,暫時不多介紹,着重於樂觀鎖的實現。
          樂觀鎖,使用版本標識來確定讀到的數據與提交時的數據是否一致。提交後修改版本標識,不一致時可以採取丟棄和再次嘗試的策略。
           記錄1,id,status1,status2,stauts3,version,表示有三個不同的狀態,以及數據當前的版本
           操作1:update table set status1=1,status2=0,status3=0 where id=111;  
           操作2:update table set status1=0,status2=1,status3=0 where id=111;
           操作3:update table set status1=0,status2=0,status3=1 where id=111;
           沒有任何控制的情況下,順序執行3個操作,最後前兩個操作會被直接覆蓋。
           加上version字段,每一次的操作都會更新version,提交時如果version不匹配,停止本次提交,可以嘗試下一次的提交,以保證拿到的是操作1提交後的結果。
          這是一種經典的樂觀鎖實現。
          另外,java中的compareandswap即cas,解決多線程並行情況下使用鎖造成性能損耗的一種機制。
          CAS操作包含三個操作數,內存位置(V),預期原值(A)和新值(B)。如果內存位置的值與預期原值相匹配,那麼處理器會西東將該位置值更新爲新值。否則,處理器不做任何操作。
          記錄2: id,stauts,status 包含3種狀態值 1,2,3
           操作,update status=3 where id=111 and status=1;
           即 如果內存值爲1,預期值爲1,則修改新值。對於沒有執行的操作則丟棄。
          思考:這兩種方式有什麼區別?
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章