1. 程式人生 > >樂觀鎖的兩種實現方式

樂觀鎖的兩種實現方式

什麼場景下需要使用鎖?

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

鎖的實現方式

          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,則修改新值。對於沒有執行的操作則丟棄。           思考:這兩種方式有什麼區別?