成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術文章
文章詳情頁

詳解mysql 中的鎖結構

瀏覽:207日期:2023-10-10 10:38:48

Mysql 支持3中鎖結構

表級鎖,開銷小,加鎖快,不會出現死鎖,鎖定的粒度大,沖突概率高,并發度最低 行級鎖,開銷小,加鎖慢,會出現死鎖,鎖定粒度小,沖突概率最低,并發度最高 頁面鎖,開銷和加鎖處于表鎖和行鎖之間,會出現死鎖,鎖粒度基于表和行之間,并發一般

InnoDB鎖問題

InnoDB與MyISAM的最大不同有兩點:一是支持事務(TRANSACTION);二是采用了行級鎖。 行級鎖和表級鎖本來就有許多不同之處,另外,事務的引入也帶來了一些新問題。

InnoDB的行鎖模式及加鎖方法

InnoDB實現了以下兩種類型的行鎖。

共享鎖(s):允許一個事務去讀一行,阻止其他事務獲得相同數據集的排他鎖。 排他鎖(X):允許獲取排他鎖的事務更新數據,阻止其他事務取得相同的數據集共享讀鎖和排他寫鎖。

另外,為了允許行鎖和表鎖共存,實現多粒度鎖機制,InnoDB還有兩種內部使用的意向鎖(Intention Locks),這兩種意向鎖都是表鎖。

意向共享鎖(IS):事務打算給數據行共享鎖,事務在給一個數據行加共享鎖前必須先取得該表的IS鎖。 意向排他鎖(IX):事務打算給數據行加排他鎖,事務在給一個數據行加排他鎖前必須先取得該表的IX鎖。 當前鎖模式和請求鎖模式 X IX S IS X 沖突 沖突 沖突 沖突 IX 沖突 兼容 沖突 兼容 S 沖突 沖突 兼容 兼容 IS 沖突 兼容 兼容 兼容

InnoDB行鎖是通過索引上的索引項來實現的,這一點MySQL與Oracle不同,后者是通過在數據中對相應數據行加鎖來實現的。InnoDB這種行鎖實現特點意味者:只有通過索引條件檢索數據,InnoDB才會使用行級鎖,否則,InnoDB將使用表鎖!

Next-Key鎖

當我們用范圍條件而不是相等條件檢索數據,并請求共享或排他鎖時,InnoDB會給符合條件的已有數據的索引項加鎖;對于鍵值在條件范圍內但并不存在的記錄,叫做“間隙(GAP)”,InnoDB也會對這個“間隙”加鎖,這種鎖機制不是所謂的間隙鎖(Next-Key鎖)。舉例來說,假如emp表中只有101條記錄,其empid的值分別是1,2,...,100,101,下面的SQL:

SELECT * FROM emp WHERE empid > 100 FOR UPDATE

是一個范圍條件的檢索,InnoDB不僅會對符合條件的empid值為101的記錄加鎖,也會對empid大于101(這些記錄并不存在)的“間隙”加鎖。InnoDB使用間隙鎖的目的,一方面是為了防止幻讀,以滿足相關隔離級別的要求,對于上面的例子,要是不使用間隙鎖,如果其他事務插入了empid大于100的任何記錄,那么本事務如果再次執行上述語句,就會發生幻讀;另一方面,是為了滿足其恢復和復制的需要。有關其恢復和復制對機制的影響,以及不同隔離級別下InnoDB使用間隙鎖的情況。很顯然,在使用范圍條件檢索并鎖定記錄時,InnoDB這種加鎖機制會阻塞符合條件范圍內鍵值的并發插入,這往往會造成嚴重的鎖等待。因此,在實際開發中,尤其是并發插入比較多的應用,我們要盡量優化業務邏輯,盡量使用相等條件來訪問更新數據,避免使用范圍條件。

什么時候使用表鎖?

對于InnoDB表,在絕大部分情況下都應該使用行級鎖,因為事務和行鎖往往是我們之所以選擇InnoDB表的理由。但在個另特殊事務中,也可以考慮使用表級鎖。

第一種情況是:事務需要更新大部分或全部數據,表又比較大,如果使用默認的行鎖,不僅這個事務執行效率低,而且可能造成其他事務長時間鎖等待和鎖沖突,這種情況下可以考慮使用表鎖來提高該事務的執行速度。

第二種情況是:事務涉及多個表,比較復雜,很可能引起死鎖,造成大量事務回滾。這種情況也可以考慮一次性鎖定事務涉及的表,從而避免死鎖、減少數據庫因事務回滾帶來的開銷。

當然,應用中這兩種事務不能太多,否則,就應該考慮使用MyISAM表。 在InnoDB下 ,使用表鎖要注意以下兩點。

(1)使用LOCK TALBES雖然可以給InnoDB加表級鎖,但必須說明的是,表鎖不是由InnoDB存儲引擎層管理的,而是由其上一層MySQL Server負責的,僅當autocommit=0、innodb_table_lock=1(默認設置)時,InnoDB層才能知道MySQL加的表鎖,MySQL Server才能感知InnoDB加的行鎖,這種情況下,InnoDB才能自動識別涉及表級鎖的死鎖;否則,InnoDB將無法自動檢測并處理這種死鎖。

(2)在用LOCAK TABLES對InnoDB鎖時要注意,要將AUTOCOMMIT設為0,否則MySQL不會給表加鎖;事務結束前,不要用UNLOCAK TABLES釋放表鎖,因為UNLOCK TABLES會隱含地提交事務;COMMIT或ROLLBACK產不能釋放用LOCAK TABLES加的表級鎖,必須用UNLOCK TABLES釋放表鎖,正確的方式見如下語句。 例如,如果需要寫表t1并從表t讀,可以按如下做:

SET AUTOCOMMIT=0;LOCAK TABLES t1 WRITE, t2 READ, ...;[do something with tables t1 and here];COMMIT;UNLOCK TABLES;

死鎖

在InnoDB中,除單個SQL組成的事務外,鎖是逐步獲得的,這就決定了InnoDB發生死鎖是可能的。 發生死鎖后,InnoDB一般都能自動檢測到,并使一個事務釋放鎖并退回,另一個事務獲得鎖,繼續完成事務。但在涉及外部鎖,或涉及鎖的情況下,InnoDB并不能完全自動檢測到死鎖,這需要通過設置鎖等待超時參數innodb_lock_wait_timeout來解決。需要說明的是,這個參數并不是只用來解決死鎖問題,在并發訪問比較高的情況下,如果大量事務因無法立即獲取所需的鎖而掛起,會占用大量計算機資源,造成嚴重性能問題,甚至拖垮數據庫。我們通過設置合適的鎖等待超時閾值,可以避免這種情況發生。

通常來說,死鎖都是應用設計的問題,通過調整業務流程、數據庫對象設計、事務大小、以及訪問數據庫的SQL語句,絕大部分都可以避免。下面就通過實例來介紹幾種死鎖的常用方法。

(1)在應用中,如果不同的程序會并發存取多個表,應盡量約定以相同的順序為訪問表,這樣可以大大降低產生死鎖的機會。如果兩個session訪問兩個表的順序不同,發生死鎖的機會就非常高!但如果以相同的順序來訪問,死鎖就可能避免。

(2)在程序以批量方式處理數據的時候,如果事先對數據排序,保證每個線程按固定的順序來處理記錄,也可以大大降低死鎖的可能。

(3)在事務中,如果要更新記錄,應該直接申請足夠級別的鎖,即排他鎖,而不應該先申請共享鎖,更新時再申請排他鎖,甚至死鎖。

(4)在REPEATEABLE-READ隔離級別下,如果兩個線程同時對相同條件記錄用SELECT...ROR UPDATE加排他鎖,在沒有符合該記錄情況下,兩個線程都會加鎖成功。程序發現記錄尚不存在,就試圖插入一條新記錄,如果兩個線程都這么做,就會出現死鎖。這種情況下,將隔離級別改成READ COMMITTED,就可以避免問題。

(5)當隔離級別為READ COMMITED時,如果兩個線程都先執行SELECT...FOR UPDATE,判斷是否存在符合條件的記錄,如果沒有,就插入記錄。此時,只有一個線程能插入成功,另一個線程會出現鎖等待,當第1個線程提交后,第2個線程會因主鍵重出錯,但雖然這個線程出錯了,卻會獲得一個排他鎖!這時如果有第3個線程又來申請排他鎖,也會出現死鎖。對于這種情況,可以直接做插入操作,然后再捕獲主鍵重異常,或者在遇到主鍵重錯誤時,總是執行ROLLBACK釋放獲得的排他鎖。

MyISAM 和 InnoDB 區別

對于MyISAM的表鎖,主要有以下幾點

(1)共享讀鎖(S)之間是兼容的,但共享讀鎖(S)和排他寫鎖(X)之間,以及排他寫鎖之間(X)是互斥的,也就是說讀和寫是串行的。(2)在一定條件下,MyISAM允許查詢和插入并發執行,我們可以利用這一點來解決應用中對同一表和插入的鎖爭用問題。(3)MyISAM默認的鎖調度機制是寫優先,這并不一定適合所有應用,用戶可以通過設置LOW_PRIPORITY_UPDATES參數,或在INSERT、UPDATE、DELETE語句中指定LOW_PRIORITY選項來調節讀寫鎖的爭用。(4)由于表鎖的鎖定粒度大,讀寫之間又是串行的,因此,如果更新操作較多,MyISAM表可能會出現嚴重的鎖等待,可以考慮采用InnoDB表來減少鎖沖突。

對于InnoDB表,主要有以下幾點

(1)InnoDB的行銷是基于索引實現的,如果不通過索引訪問數據,InnoDB會使用表鎖。(2)InnoDB間隙鎖機制,以及InnoDB使用間隙鎖的原因。(3)在不同的隔離級別下,InnoDB的鎖機制和一致性讀策略不同。(4)MySQL的恢復和復制對InnoDB鎖機制和一致性讀策略也有較大影響。(5)鎖沖突甚至死鎖很難完全避免。

在了解InnoDB的鎖特性后,用戶可以通過設計和SQL調整等措施減少鎖沖突和死鎖,包括:

盡量使用較低的隔離級別 精心設計索引,并盡量使用索引訪問數據,使加鎖更精確,從而減少鎖沖突的機會。 選擇合理的事務大小,小事務發生鎖沖突的幾率也更小。 給記錄集顯示加鎖時,最好一次性請求足夠級別的鎖。比如要修改數據的話,最好直接申請排他鎖,而不是先申請共享鎖,修改時再請求排他鎖,這樣容易產生死鎖。 不同的程序訪問一組表時,應盡量約定以相同的順序訪問各表,對一個表而言,盡可能以固定的順序存取表中的行。這樣可以大減少死鎖的機會。 盡量用相等條件訪問數據,這樣可以避免間隙鎖對并發插入的影響。 不要申請超過實際需要的鎖級別;除非必須,查詢時不要顯示加鎖。 對于一些特定的事務,可以使用表鎖來提高處理速度或減少死鎖的可能

MySql樂觀鎖悲觀鎖

悲觀鎖

悲觀鎖的特點是先獲取鎖,再進行業務操作,即“悲觀”的認為獲取鎖是非常有可能失敗的,因此要先確保獲取鎖成功再進行業務操作。通常所說的“一鎖二查三更新”即指的是使用悲觀鎖。通常來講在數據庫上的悲觀鎖需要數據庫本身提供支持,即通過常用的select … for update操作來實現悲觀鎖。當數據庫執行select for update時會獲取被select中的數據行的行鎖,因此其他并發執行的select for update如果試圖選中同一行則會發生排斥(需要等待行鎖被釋放),因此達到鎖的效果。select for update獲取的行鎖會在當前事務結束時自動釋放,因此必須在事務中使用。

這里需要注意的一點是不同的數據庫對select for update的實現和支持都是有所區別的,例如oracle支持select for update no wait,表示如果拿不到鎖立刻報錯,而不是等待,mysql就沒有no wait這個選項。另外mysql還有個問題是select for update語句執行中所有掃描過的行都會被鎖上,這一點很容易造成問題。因此如果在mysql中用悲觀鎖務必要確定走了索引,而不是全表掃描。

樂觀鎖

樂觀鎖的特點先進行業務操作,不到萬不得已不去拿鎖。即“樂觀”的認為拿鎖多半是會成功的,因此在進行完業務操作需要實際更新數據的最后一步再去拿一下鎖就好。

樂觀鎖在數據庫上的實現完全是邏輯的,不需要數據庫提供特殊的支持。一般的做法是在需要鎖的數據上增加一個版本號,或者時間戳,然后按照如下方式實現:

1. SELECT data AS old_data, version AS old_version FROM …;2. 根據獲取的數據進行業務操作,得到new_data和new_version3. UPDATE SET data = new_data, version = new_version WHERE version = old_versionif (updated row > 0) { // 樂觀鎖獲取成功,操作完成} else { // 樂觀鎖獲取失敗,回滾并重試}

在數據庫內部update同一行的時候是不允許并發的,即數據庫每次執行一條update語句時會獲取被update行的寫鎖,直到這一行被成功更新后才釋放。因此在業務操作進行前獲取需要鎖的數據的當前版本號,然后實際更新數據時再次對比版本號確認與之前獲取的相同,并更新版本號,即可確認這之間沒有發生并發的修改。如果更新失敗即可認為老版本的數據已經被并發修改掉而不存在了,此時認為獲取鎖失敗,需要回滾整個業務操作并可根據需要重試整個過程。

樂觀鎖在不發生取鎖失敗的情況下開銷比悲觀鎖小,但是一旦發生失敗回滾開銷則比較大,因此適合用在取鎖失敗概率比較小的場景,可以提升系統并發性能樂觀鎖還適用于一些比較特殊的場景,例如在業務操作過程中無法和數據庫保持連接等悲觀鎖無法適用的地方

以上就是詳解mysql 中的鎖結構的詳細內容,更多關于MySQL 鎖結構的資料請關注好吧啦網其它相關文章!

標簽: MySQL 數據庫
相關文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
国产精品久久网站| 成人午夜视频网站| 日韩国产精品久久久久久亚洲| 成人妖精视频yjsp地址| 老司机午夜精品视频| 国产精品家庭影院| 国产高清精品网站| 国产日韩欧美高清免费| 26uuu欧美日本| 欧美最猛性xxxxx直播| 玉米视频成人免费看| 91在线观看地址| 337p亚洲精品色噜噜| 亚洲小说欧美激情另类| 激情欧美亚洲| 久久精品亚洲精品国产欧美kt∨ | 亚洲高清视频中文字幕| 欧美日韩精品综合| 在线看日本不卡| 丝袜美腿一区二区三区| 国产精品日韩欧美一区| 国产精品夫妻自拍| 91在线精品秘密一区二区| 日韩一区二区三区电影在线观看 | 精品国产乱码久久久久久图片| 日本欧美一区二区三区| 99亚洲视频| 亚洲成人第一页| 在线看片欧美| 国产精品久久免费看| 色综合视频在线观看| 这里只有精品免费| 蜜臀av性久久久久蜜臀aⅴ流畅| 性欧美暴力猛交另类hd| 亚洲国产一区二区三区青草影视| 欧美日韩一区二区视频在线| 国产亚洲一区字幕| fc2成人免费人成在线观看播放 | 亚洲精品伦理在线| 亚洲视频免费| 国产精品久久久久婷婷二区次| 欧美精选一区| 国产偷国产偷精品高清尤物| 91亚洲精品一区二区乱码| 亚洲精品在线三区| av网站免费线看精品| 精品嫩草影院久久| www.av精品| 国产亚洲欧美在线| 欧美午夜精品久久久久免费视| 国产精品午夜电影| 国产综合色一区二区三区| 中文字幕国产精品一区二区| 欧美一区激情| 国产欧美一区二区三区鸳鸯浴| 欧美激情偷拍| 国产精品久久久久婷婷| 精品1区2区| 亚洲综合色丁香婷婷六月图片| 成人精品电影在线观看| 精品国产乱码久久久久久老虎 | 亚洲国产cao| 久久久久久国产精品mv| 日韩精品一卡二卡三卡四卡无卡| 日本精品视频一区二区三区| 久久国产综合精品| 91麻豆精品国产自产在线观看一区 | 亚洲乱码一区二区三区在线观看| 亚洲高清精品中出| 亚洲小说春色综合另类电影| 老牛嫩草一区二区三区日本| 久久成人综合网| 欧美大肚乱孕交hd孕妇| 欧美搞黄网站| 亚洲激情网站免费观看| 亚洲欧美日本国产专区一区| 日本在线不卡视频一二三区| 欧美日韩dvd在线观看| 成人福利在线看| 欧美激情综合在线| 99xxxx成人网| 蜜臀av性久久久久蜜臀av麻豆| 欧美一区二区三区视频在线| 99久久婷婷国产综合精品电影| 国产精品国产三级国产专播品爱网| 国产精品一区视频| 激情六月婷婷综合| 欧美成人a在线| 亚洲图片在线观看| 奇米影视一区二区三区小说| 日韩精品专区在线影院重磅| 欧美日韩a区| 视频一区二区中文字幕| 日韩精品中文字幕在线一区| 黄色亚洲在线| 日本在线观看不卡视频| 欧美一区二区福利在线| 亚洲私拍自拍| 人人爽香蕉精品| 久久久综合精品| 国产精品久久波多野结衣| 国产精品一区二区在线观看网站 | 3751色影院一区二区三区| 99国产精品久久久久久久久久久| 欧美韩国日本一区| 欧美一级视频| 成人精品电影在线观看| 一区二区三区色| 91精品国产福利| 狠狠综合久久| 久久超碰97中文字幕| 国产清纯在线一区二区www| 美女主播一区| av电影在线观看完整版一区二区| 一区二区三区鲁丝不卡| 3d动漫精品啪啪一区二区竹菊| 亚洲午夜精品久久久久久浪潮| 蜜臀精品久久久久久蜜臀| 久久久国产午夜精品| 亚洲一区高清| 国产成人综合精品三级| 亚洲人成7777| 欧美一区二区啪啪| 一本久道久久久| 丁香另类激情小说| 亚洲chinese男男1069| 久久久久久夜精品精品免费| 久热这里只精品99re8久| 99re6这里只有精品视频在线观看| 亚洲国产一区视频| 久久综合中文字幕| 日本电影欧美片| 国语自产精品视频在线看抢先版结局 | 99re亚洲国产精品| 午夜不卡av在线| 国产午夜亚洲精品午夜鲁丝片 | 国产欧美三级| 99re8在线精品视频免费播放| 日本欧美一区二区| 国产精品嫩草影院av蜜臀| 欧美日韩视频在线一区二区 | 成人av动漫在线| 日本欧美一区二区在线观看| 国产精品婷婷午夜在线观看| 欧美一区三区二区| 久久国产精品高清| 欧美女激情福利| 国产二区国产一区在线观看| 天天影视网天天综合色在线播放| 欧美高清一级片在线观看| 欧美精品一级二级三级| 亚洲资源av| 国模 一区 二区 三区| 懂色av一区二区三区免费看| 五月婷婷另类国产| 国产精品久久三区| 欧美成人a∨高清免费观看| 91行情网站电视在线观看高清版| 伊人久久亚洲影院| 99久久亚洲一区二区三区青草| 久久国产精品一区二区| 亚洲综合一区二区三区| 欧美国产精品一区| 欧美精品一区二区三区视频| 欧美精品亚洲二区| 在线免费不卡电影| 先锋a资源在线看亚洲| 在线日韩av| 欧美 日韩 国产精品免费观看| 国产美女av一区二区三区| 婷婷久久综合九色国产成人| 一色屋精品亚洲香蕉网站| 亚洲精品一区二区在线观看| 6080亚洲精品一区二区| 欧美性一二三区| 色婷婷综合久久久久中文一区二区 | 国产日韩精品一区二区浪潮av| 欧美日韩成人一区二区| 色哟哟国产精品免费观看| 宅男噜噜噜66国产日韩在线观看| 欧美一区免费视频| 成人国产在线观看| 国产精品伊人色| 激情综合网最新| 秋霞影院一区二区| 日韩avvvv在线播放| 午夜精品一区在线观看| 亚洲精品国产视频| 亚洲日本va午夜在线影院| 欧美国产日本韩| 久久日一线二线三线suv| 日韩欧美在线影院| 91精品在线免费观看| 制服丝袜一区二区三区| 欧美精品乱码久久久久久| 欧洲av在线精品| 欧美午夜片在线看| 欧美性色aⅴ视频一区日韩精品| 色综合久久九月婷婷色综合| 91激情五月电影|