???💝💝💝歡迎來到我的博客,很高興能夠在這里和您見面!希望您在這里可以感受到一份輕松愉快的氛圍,不僅可以獲得有趣的內容和知識,也可以暢所欲言、分享您的想法和見解。
非常期待和您一起在這個小小的網絡世界里共同探索、學習和成長。💝💝💝 ?? 歡迎訂閱本專欄 ??
?
前言
小鄭最近在準備Go語言的面試題,通過github和b站等各種學習網站上學習go語言的八股文,并且整理出自己覺得面試可能會問到的知識點,希望通過做筆記的方式來鞏固自己的知識點,并且也希望可以幫助到大家在面試的時候更加得心應手一些,那么從現在開始,和我一起加入八股學習之旅吧!
1.為什么要加鎖?
當多個用戶并發地存取數據時,在數據庫中就會產生多個事務同時存取同一數據的情況。若對并發操作不加控制就可能會讀取和存儲不正確的數據,破壞數據庫的一致性。 保證多用戶環境下保證數據庫完整性和一致性。
2.按照鎖的粒度分數據庫鎖有哪些?
在關系型數據庫中,可以按照鎖的粒度把數據庫鎖分為行級鎖(INNODB引擎)、表級鎖(MYISAM引擎 )和頁級鎖(BDB引擎 )。 行級鎖
- 行級鎖是MySQL中鎖定粒度最細的一種鎖,表示只針對當前操作的行進行加鎖。行級鎖能大大減少數據庫操作的沖突。其加鎖粒度最小,但加鎖的開銷也最大。行級鎖分為共享鎖 和 排他鎖。
- 開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖沖突的概率最低,并發度也最高。
表級鎖
- 表級鎖是MySQL中鎖定粒度最大的一種鎖,表示對當前操作的整張表加鎖,它實現簡單,資源消耗較少,被大部分MySQL引擎支持。最常使用的MYISAM與INNODB都支持表級鎖定。表級鎖定分為表共享讀鎖(共享鎖)與表獨占寫鎖(排他鎖)。
- 開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發出鎖沖突的概率最高,并發度最低。
頁級鎖
- 頁級鎖是MySQL中鎖定粒度介于行級鎖和表級鎖中間的一種鎖。表級鎖速度快,但沖突多,行級沖突少,但速度慢。所以取了折衷的頁級,一次鎖定相鄰的一組記錄。BDB支持頁級鎖
- 開銷和加鎖時間界于表鎖和行鎖之間;會出現死鎖;鎖定粒度界于表鎖和行鎖之間,并發度一般
MyISAM和InnoDB存儲引擎使用的鎖:
- MyISAM采用表級鎖(table-level locking)。
- InnoDB支持行級鎖(row-level locking)和表級鎖,默認為行級鎖
3.從鎖的類別上分MySQL都有哪些鎖呢?
從鎖的類別上來講,有共享鎖和排他鎖。
- 共享鎖: 又叫做讀鎖。 當用戶要進行數據的讀取時,對數據加上共享鎖。共享鎖可以同時加上多個。
- 排他鎖: 又叫做寫鎖。 當用戶要進行數據的寫入時,對數據加上排他鎖。排他鎖只可以加一個,他和其他的排他鎖,共享鎖都相斥。
用上面的例子來說就是用戶的行為有兩種,一種是來看房,多個用戶一起看房是可以接受的。 一種是真正的入住一晚,在這期間,無論是想入住的還是想看房的都不可以。 鎖的粒度取決于具體的存儲引擎,InnoDB實現了行級鎖,頁級鎖,表級鎖。 他們的加鎖開銷從大到小,并發能力也是從大到小。
4.數據庫的樂觀鎖和悲觀鎖是什么?怎么實現的?
- 悲觀鎖:假定會發生并發沖突,屏蔽一切可能違反數據完整性的操作。在查詢完數據的時候就把事務鎖起來,直到提交事務。實現方式:使用數據庫中的鎖機制? (多寫)
- 樂觀鎖:假設不會發生并發沖突,只在提交操作時檢查是否違反數據完整性。在修改數據的時候把事務鎖起來,通過version的方式來進行鎖定。實現方式:樂一般會使用版本號機制或CAS算法實現。 (多讀場景)
版本號(version)方式是一種實現樂觀鎖的常見方法,通常用于并發控制。其基本原理是給每條數據記錄增加一個版本號,每次數據更新時,版本號都會遞增。在更新操作時,系統會先檢查該數據的版本號是否與當前操作時數據庫中存儲的版本號一致,如果一致則允許更新,否則說明數據已經被其他事務修改過,更新操作會被拒絕,事務需要重新執行。
5.InnoDB引擎的行鎖是怎么實現的?
InnoDB是通過索引來實現行鎖的,如果查詢條件列是表的索引列,那么innoDB會根據索引定位到特點的行,并且對這些行進行加鎖,確保事務完成之前其他事務沒辦法修改這些行。
如果是非索引列,那么innoDB就會對表進行全表掃描,這個過程會導致表鎖,所以也意味著沒辦法并發執行操作。
6.什么是死鎖?怎么解決?
死鎖是指兩個或多個事務在同一資源上相互占用,并請求鎖定對方的資源,從而導致惡性循環的現象。 常見的解決死鎖的方法 1、如果不同程序會并發存取多個表,盡量約定以相同的順序訪問表,可以大大降低死鎖機會。?2、在同一個事務中,盡可能做到一次鎖定所需要的所有資源,減少死鎖產生概率; 3、對于非常容易產生死鎖的業務部分,可以嘗試使用升級鎖定顆粒度,通過表級鎖定來減少死鎖產生的概率; 如果業務處理不好可以用分布式事務鎖或者使用樂觀鎖
7.隔離級別與鎖的關系
1.在Read Uncommitted級別下,讀取數據不需要加共享鎖,這樣就不會跟被修改的數據上的排他鎖沖突
2.在Read Committed級別下,讀操作需要加共享鎖,但是在語句執行完以后釋放共享鎖;
與鎖的關系:在事務執行過程中,對讀取的數據行會加共享鎖,確保其他事務無法修改正在讀取的數據,直到讀取完成。
3.在Repeatable Read級別下,讀操作需要加共享鎖,但是在事務提交之前并不釋放共享鎖,也就是必須等待事務執行完畢以后才釋放共享鎖。
與鎖的關系:在事務開始時,讀取的數據會被鎖住(共享鎖),在整個事務生命周期中,不會釋放這些鎖,從而保證數據的一致性。其他事務無法修改或插入相同范圍的數據,直到當前事務完成。
4.SERIALIZABLE 是限制性最強的隔離級別,因為該級別鎖定整個范圍的鍵,并一直持有鎖,直到事務完成。
與鎖的關系:該級別會鎖定整個數據范圍(包括正在讀取的所有數據行),直到事務結束,因此會阻止其他事務修改、刪除或插入范圍內的任何數據。
隔離級別 | 鎖類型 | 鎖的持續時間 | 可能出現的并發問題 |
---|---|---|---|
Read Uncommitted | 無鎖 | 無鎖 | 臟讀、不可重復讀、幻讀 |
Read Committed | 共享鎖(讀取時加) | 讀取完后釋放 | 不可重復讀、幻讀 |
Repeatable Read | 共享鎖(讀取時加) | 持續到事務結束 | 幻讀 |
Serializable | 范圍鎖(鎖住數據范圍) | 直到事務完成 | 無臟讀、不可重復讀、幻讀 |
??????小鄭是普通學生水平,如有紕漏,歡迎各位大佬評論批評指正!😄😄😄
💘💘💘如果覺得這篇文對你有幫助的話,也請給個點贊、收藏下吧,非常感謝!👍 👍 👍