1、簡介
鎖是計算機協調多個進程或純線程並發訪問某一資源的機制。在數據庫中,除傳統的計算資源(CPU、RAM、I/O)的爭用以外,數據也是一種供許多用戶共享的資源。如何保證數據並發訪問的一致性、有效性是所在有數據庫必須解決的一個問題,鎖沖突也是影響數據庫並發訪問性能的一個重要因素。從這個角度來說,鎖對數據庫而言顯得尤其重要,也更加復雜。
防止更新丟失,並不能單靠數據庫事務控制器來解決,需要應用程序對要更新的數據加必要的鎖來解決。
鎖的運作?
事務T在度某個數據對象(如表、記錄等)操作之前,先向系統發出請求,對其加鎖,加鎖后事務T就對數據庫對象有一定的控制,在事務T釋放它的鎖之前,其他事務不能更新此數據對象。
2、鎖的類別
1)排他鎖:(又稱寫鎖,X鎖)
一句總結:會阻塞其他事務讀和寫。
若事務T對數據對象A加上X鎖,則只允許T讀取和修改A,其他任何事務都不能再對加任何類型的鎖,直到T釋放A上的鎖。這就保證了其他事務在T釋放A上的鎖之前不能再讀取和修改A。
2)共享鎖:(又稱讀取,S鎖)
一句總結:會阻塞其他事務修改表數據。
若事務T對數據對象A加上S鎖,則其他事務只能再對A加S鎖,而不能X鎖,直到T釋放A上的鎖。這就保證了其他事務可以讀A,但在T釋放A上的S鎖之前不能對A做任何修改。
X鎖和S鎖都是加載某一個數據對象上的。也就是數據的粒度。
按封鎖的數據粒度分類如下:
1)行級鎖定(row-level):
一句總結:行級鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖沖突的概率最低,並發度也最高。
詳細:行級鎖定最大的特點就是鎖定對象的顆粒度很小,也是目前各大數據庫管理軟件所實現的鎖定顆粒度最小的。由於鎖定顆粒度很小,所以發生鎖定資源爭用的概率也最小,能夠給予應用程序盡可能大的並發處理能力而提高一些需要高並發應用系統的整體性能。
缺陷:由於鎖定資源的顆粒度很小,所以每次獲取鎖和釋放鎖需要做的事情也更多,帶來的消耗自然也就更大了。此外,行級鎖定也最容易發生死鎖。
2)表級鎖定(table-level):
一句總結:表級鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖沖突的概率最高,並發度最低。
詳細:和行級鎖定相反,表級別的鎖定是MySQL各存儲引擎中最大顆粒度的鎖定機制。該鎖定機制最大的特點是實現邏輯非常簡單,帶來的系統負面影響最小。所以獲取鎖和釋放鎖的速度很快。由於表級鎖一次會將整個表鎖定,所以可以很好的避免困擾我們的死鎖問題。
缺陷:鎖定顆粒度大所帶來最大的負面影響就是出現鎖定資源爭用的概率也會最高,致使並發度大打折扣。
3)頁級鎖定(page-level):(MySQL特有)
一句總結:頁級鎖:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,並發度一般。
詳細:頁級鎖定是MySQL中比較獨特的一種鎖定級別,在其他數據庫管理軟件中也並不是太常見。頁級鎖定的特點是鎖定顆粒度介於行級鎖定與表級鎖之間,所以獲取鎖定所需要的資源開銷,以及所能提供的並發處理能力也同樣是介於上面二者之間。
缺陷:頁級鎖定和行級鎖定一樣,會發生死鎖。
從這里我們應該引申去思考行鎖更多的缺點:(因為我們執行sql主要依賴行鎖來提高並發度)
1- 比表級鎖、頁級鎖消耗更多內存
2- 如果你在大部分數據上經常進行GROUP BY操作或者必須經常掃描整個表,比其它鎖定明顯慢很多。
3- 更容易發生死鎖。