關於鎖的討論

2022-08-29 13:30:24 字數 2068 閱讀 6591

一、背景:併發問題一直是企業架構不能忽視的問題,也就是說不可以高枕無憂,始終有些地方你是忽略掉的,對同一片資料庫,不同執行緒同時訪問就會出現併發,併發業務性併發和資料庫併發,事務系統的出現就是為了解決這種併發問題,事務也是利用鎖的原理,鎖定後只允許乙個請求獲得資源,當然事務中的鎖要視事務隔離性而定,現在我們來討論下關於鎖和事務;

二、鎖分為悲觀鎖和樂觀鎖,悲觀鎖是在乙個請求獲得資源並且釋放鎖後另乙個請求才能獲得資源,樂觀鎖是乙個請求獲得資源,但允許另乙個請求也獲得資源,但是第乙個請求修改並提交資源時,另乙個請求修改並提交的時候會提交不成功,這裡可以有合併操作的處理,例如svn**的版本控制,也可以另乙個提交失敗;

三、.net環境中的鎖,基元執行緒同步構造包含使用者模式構造和核心模式構造,基元就是可以在**中使用的最簡單的構造,使用者模式構造提供易變構造,它在包含乙個簡單變數上執行原子性讀和寫操作,例如system.threading.volatie類提供的volatie.write\volatie.read方法,或者在字段標記關鍵字volatie;互鎖構造,和易變構造定義一樣,都是對簡單資料型別變數上執行原子性操作,system.threading.interlocked建立完整記憶體柵欄,也就是說呼叫interlocked方法之前任何變數寫入都在呼叫interlocked方法之前寫入,這個呼叫之後的任何變數讀取都在這個呼叫之後讀取,後一句可能大家不能理解,這裡解析下,就是說c#編譯器將**轉換成中間語言il,jit編譯器將其轉換成cpu的時候,可能將兩個變數賦值的順序反轉,這個時候,編譯**的時候現將變數從ram讀入cpu暫存器,這個時候可能先讀入乙個變數,同時另一線程將這個變數賦值,而你不知情;核心模式構造和混合模式(lock)鎖另外章節討論;

四、分布式鎖,分布式鎖將訪問的資源鎖定,同一時間只有乙個使用者可以訪問這類資源,例如時下的搖一搖,對整個業務同一時刻只允許一次訪問,於是利用redis、memcached的原子性操作,將整個業務對同乙個使用者進行鎖定,處理完之後再允許下一次操作,分布式鎖不能使用資料庫的原子性操作,只能是redis、memcached、zookeeper這種外部資源;

1、首先memcached提供過的函式set,在多執行緒訪問時,set函式都會成功,但是會以最後乙個執行緒set為準,而add函式則相反第乙個執行緒add函式會成功返回true,其他執行緒set都會返回false,利用memcached比較高效,但如果memcached記憶體不夠就會丟失鎖,導致死鎖,又因為memcache沒有持久化,因此宕機重啟後鎖丟失;

2、zookeeper,基於zookeeper瞬時有序節點,當加鎖時與該功能對應的指定節點的目錄下,生成乙個唯一的瞬時有序節點,當釋放鎖的時候,只需將這個瞬時節點刪除即可,因為可以持久化,所以防止宕機時重啟時,丟失鎖資訊;

3、redis原子性操作,與memcached一樣利用add函式的原子性操作也可以實現分布式鎖;

五、資料庫中的事務,資料庫中的鎖其他章節討論,資料庫或軟體事務都使用acid屬性來描述,分別是原子性,即一系列動作步驟,要麼全部成功,要麼全部失敗;一致性,事務開始到結束,系統資源必須一致,如果中途出現故障,一部分寫入是無效的,中間狀態沒有遭到破壞;隔離性,乙個事務中的資料和操作相對與其他事務具有隔離性,併發事務之間並不干擾;永續性,一旦提交成功,提交後的資料將永久存在,即使系統崩潰也能持久儲存下來;如果系統總是使用全完隔離的事務,將會降低系統吞吐率,為了提供系統靈活性,事務可以減少隔離性,事務的隔離性一般分為4個種類,如下介紹:

1、可序列化事務(serializable),可串化事務是隔離級別最高的一種,使用可串化級別事務可以避免髒讀、幻讀、不可重複讀,使用此種事務,各個事務之間相互隔離,會以某種順序執行這些事務,但系統吞吐率受到影響;

2、可重複度(repeatable read),就是說a事務讀取了資料a,那麼b事務就不能對a資料進行修改,必須等待a事務提交,你可能會說和序列化事務有什麼區別,區別就是序列化會鎖定資源的表,你不可以插入資料造成幻讀;

3、不可重複度或者讀已提交(read committed),a使用者讀取了a資料,b使用者對a進行操作,這時候a要等b修改完提交事務才能修改a資料;

4、讀未提交(read uncommitted),這種事務隔離級別最低,就是說a對a資料進行修改的時候,b可以讀取到a修改但未提交的資料,a可能回滾了,但b讀的是髒讀資料;和不可重複讀區別在於不可重複讀,是讀取的時提交後的資料;

其他鎖在後續完善

關於鎖存器問題的討論

上圖是兩個沒有else的 其等效於下圖的 也就是說,當if條件裡面沒有寫else時,預設是表示 保持不變 的意思。接下來,我們來討論一下,硬體中是如何實現 保持不變 的。左邊是時序時序邏輯的 右邊是該 所對應的硬體電路。特別注意圖中紅色的那個線,那個就是保持不變的 反饋 由圖中可以看出,當時鐘上公升...

乙個關於自旋鎖 spin lock 問題的討論

前陣子有發短訊息問 在研究自旋鎖的時候,發現在 spin lock irq函式,也就是在自旋鎖中關閉中的這類函式中,既然已經關閉了本地中斷,再禁止搶占有沒有多餘。也就是說,既然本地中斷已經禁止了,在本處理器上是無法被打斷的,本地排程器也無法執行,也就不可以被本地排程程式排程出去.從spinlock設...

關於共同生存週期的物件與鎖的討論

之前與同學在談一道smart pointer的面試題,在實現thread safe的時候發現mutex的destroy始終不好解決。問題在於,當你要destroy的mutex之前,必須先unlock這個mutex,而當你unlock這個mutex的同時,你的destroy部分可能不收保護了。與另外乙...