當我們要對乙個資料庫中的一條資料進行修改的時候,為了避免同時被其他人修改,最好的辦法就是直接對該資料進行加鎖以防止併發。
這種借助資料庫鎖機制在修改資料之前先鎖定,再修改的方式被稱之為悲觀併發控制(又名「悲觀鎖」,pessimistic concurrency control,縮寫「pcc」)。
之所以叫做悲觀鎖,是因為這是一種對資料的修改抱有悲觀態度的併發控制方式。我們一般認為資料被併發修改的概率比較大,所以需要在修改之前先加鎖。
悲觀併發控制實際上是**「先取鎖再訪問」的保守策略,為資料處理的安全提供了保證**
但是在效率方面,處理加鎖的機制會讓資料庫產生額外的開銷,還有增加產生死鎖的機會;
另外,還會降低並行性,乙個事務如果鎖定了某行資料,其他事務就必須等待該事務處理完才可以處理那行資料。
樂觀鎖( optimistic locking ) 是相對悲觀鎖而言的,樂觀鎖假設資料一般情況下不會造成衝突,所以在資料進行提交更新的時候,才會正式對資料的衝突與否進行檢測,如果發現衝突了,則讓返回使用者錯誤的資訊,讓使用者決定如何去做。
相對於悲觀鎖,在對資料庫進行處理的時候,樂觀鎖並不會使用資料庫提供的鎖機制。一般的實現樂觀鎖的方式就是記錄資料版本。
樂觀併發控制相信事務之間的資料競爭(data race)的概率是比較小的,因此盡可能直接做下去,直到提交的時候才去鎖定,所以不會產生任何鎖和死鎖。
悲觀鎖的實現,往往依靠資料庫提供的鎖機制。在資料庫中,悲觀鎖的流程如下:
注意:要使用悲觀鎖,我們必須關閉mysql資料庫中自動提交的屬性,命令set autocommit=0;即可關閉,因為mysql預設使用autocommit模式,也就是說,當你執行乙個更新操作後,mysql會立刻將結果進行提交。使用樂觀鎖就不需要借助資料庫的鎖機制了。
樂觀鎖的概念中其實已經闡述了他的具體實現細節:主要就是兩個步驟:衝突檢測和資料更新。其實現方式有一種比較典型的就是**compare and swap(cas)**技術。
cas是項樂觀鎖技術,當多個執行緒嘗試使用cas同時更新同乙個變數時,只有其中乙個執行緒能更新變數的值,而其它執行緒都失敗,失敗的執行緒並不會被掛起,而是被告知這次競爭中失敗,並可以再次嘗試。
在樂觀鎖與悲觀鎖的選擇上面,主要看下兩者的區別以及適用場景就可以了。
樂觀鎖並未真正加鎖,效率高。一旦鎖的粒度掌握不好,更新失敗的概率就會比較高,容易發生業務失敗。
悲觀鎖依賴資料庫鎖,效率低。更新失敗的概率比較低。
資料庫的悲觀鎖和樂觀鎖
資料庫的四種隔離級別 髒讀 不可重複讀 可重複讀 序列化,雖然四種隔離級別能夠處理事務問題,但是不夠靈活,於是有了悲觀鎖和樂觀鎖。悲觀鎖 對於外界的修改持保守態度,在整個資料處理中資料處於鎖定狀態。以mysql為例,select for update和lock in share model能夠實現悲...
資料庫的悲觀鎖和樂觀鎖
悲觀鎖就是對資料的衝突持悲觀態度,也就是假設資料肯定會發生衝突,所以在資料開始讀取的時候就把資料鎖定住。書籍表book,id為商品id 主鍵 isonline是否上線,1代表上線,0代表下線,那麼我們如果要對書籍進行下線,就需要將online置為0,假設id為1 如果不採用鎖 1 select fr...
資料庫悲觀鎖和樂觀鎖簡述
鎖 locking 業務邏輯的實現過程中,往往需要保證資料訪問的排他性。如在金融系統的日終結算 處理中,我們希望針對某個 cut off 時間點的資料進行處理,而不希望在結算進行過程中 可能是幾秒種,也可能是幾個小時 資料再發生變化。此時,我們就需要通過一些機 制來保證這些資料在某個操作過程中不會被...