国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

MySQL - 事務(wù)的啟動 / 設(shè)置 / 鎖 / 解鎖——入門

iOS122 / 1873人閱讀

摘要:行級鎖,頁級鎖,表級鎖。聞其名知其意,比較少見的是頁級鎖,它鎖定的是一組相鄰數(shù)據(jù)。排他鎖允許獲得排他鎖的事務(wù)更新數(shù)據(jù),阻止其他事務(wù)取得相同數(shù)據(jù)集的讀寫。意向排他鎖事務(wù)打算給數(shù)據(jù)行加行排他鎖,事務(wù)在給一個數(shù)據(jù)行加排他鎖前必須先取得該表的鎖。

廢話

本篇的名字簡直可以起成《事務(wù)操作:從入門到放棄》。

力圖解決:在MySQL 5.5 版本及更高版本時,使用事務(wù)的完整流程和細(xì)節(jié)記錄,而無需面對互聯(lián)網(wǎng)上紛繁零散的事務(wù)筆記。

實踐 - 基礎(chǔ)

首先,在你的空數(shù)據(jù)庫上(譬如Test預(yù)留數(shù)據(jù)庫),創(chuàng)建一個test表,有idtext(varchar 50)兩個字段。

請開啟兩個MySQL操作端,分別依次鍵入:

A端 B端
SET AUTOCOMMIT=0 SET AUTOCOMMIT=0
SELECT text FROM test WHERE id = 1 不輸入
UPDATE test SET text="UioSun" WHERE id = 1; UPDATE test SET text="UioYang" WHERE id = 1;

注意你的查詢提示欄,你能發(fā)現(xiàn):在A端未提交之前,默認(rèn)狀態(tài)下,B端的UPDATE是沒有反饋的——被掛起。等待一段時間后,你能收到關(guān)于Transaction失敗的消息。

這種錯誤狀態(tài)被稱為死鎖,你可以通過解鎖相關(guān)的內(nèi)容,來Kill it。

上述是很極端的情況,正常來說,事務(wù)是通過自動插入來完成,基本上可以避免死鎖情況。

這就是事務(wù)的基礎(chǔ)演示,最后,通過ROLLBACKCOMMIT,你可以完成事務(wù)的結(jié)束。

實踐 - 鎖

在上一部分,你完成了一個事務(wù)的基礎(chǔ)流程,啟動、進(jìn)行、并最終得到結(jié)果(或許是意外結(jié)果)。
至少我在上一部分結(jié)尾處,腦海中有兩個問題:

我聽過事務(wù)的鎖,它通過鎖完成獨享目標(biāo),并在完成修改后釋放它的獨享權(quán),但我該如何設(shè)置它的級別?

鎖的阻塞時間為多久?我如何檢測它?

當(dāng)然,為了另一種思路的編程玩家,我也將在本節(jié)末尾放上當(dāng)前支持鎖的優(yōu)缺比較。


行級鎖,頁級鎖,表級鎖。聞其名知其意,比較少見的是:頁級鎖,它鎖定的是一組相鄰數(shù)據(jù)。

而MySQL的不同引擎,對鎖級別支持是不一樣的,以最常用的InnoDB為代表,默認(rèn)采用行級鎖,也支持表級鎖,但這是有條件的,只有在針對索引SQL操作時,才會使用行級鎖,否則這個操作將采取表級鎖。

表級鎖鎖定的數(shù)量最多,占據(jù)內(nèi)存最多,但有在做內(nèi)部處理時中,它的操作速度是相當(dāng)快的,而且?guī)缀醪淮嬖谒梨i問題,所以在中大型內(nèi)部處理機制中,表級鎖的應(yīng)用場景大于行級鎖。

行級鎖又分為共享鎖和獨占鎖(排它鎖,翻譯差異),允許讀取的共享鎖是默認(rèn)鎖,而獨占鎖是不允許讀寫的完全占有——廢話。

共享鎖(S):允許一個事務(wù)去讀一行,阻止其他事務(wù)獲得相同數(shù)據(jù)集的排他鎖。
排他鎖(X):允許獲得排他鎖的事務(wù)更新數(shù)據(jù),阻止其他事務(wù)取得相同數(shù)據(jù)集的讀寫。
另外,為了允許行鎖和表鎖共存,實現(xiàn)多粒度鎖機制,InnoDB還有兩種內(nèi)部使用的意向鎖(Intention Locks),這兩種意向鎖都是表鎖
意向共享鎖(IS):事務(wù)打算給數(shù)據(jù)行加行共享鎖,事務(wù)在給一個數(shù)據(jù)行加共享鎖前必須先取得該表的IS鎖。
意向排他鎖(IX):事務(wù)打算給數(shù)據(jù)行加行排他鎖,事務(wù)在給一個數(shù)據(jù)行加排他鎖前必須先取得該表的IX鎖。

頁級鎖(間隙鎖)

@gaoyulong 表示:間隙鎖被吃啦?

對此我表示抱歉,之前一直了解的都是頁級鎖(也就是間隙鎖),偏偏頁級鎖在互聯(lián)網(wǎng)上的信息又不夠豐富,所以就沒考慮到。

頁級鎖是個很重要的鎖,它會鎖定一組數(shù)據(jù),但這個鎖并不是那么好用(更多的考慮是安全性)。

對于鍵值在條件范圍內(nèi)但并不存在的記錄,叫做“間隙(GAP)”,InnoDB也會對這個“間隙”加鎖,這種鎖機制就是所謂的間隙鎖(Next-Key鎖)。

InnoDB使用間隙鎖的目的,一方面是為了防止幻讀,以滿足相關(guān)隔離級別的要求,對一個AutoID 100條數(shù)據(jù)的表做ID為102的查詢,要是不使用間隙鎖,如果其他事務(wù)插入了ID大于100的任何記錄,那么本事務(wù)如果再次執(zhí)行上述語句,就會發(fā)生幻讀;另外一方面,是為了滿足其恢復(fù)和復(fù)制的需要。

本段內(nèi)容源于:間隙鎖(Next-Key鎖) - xiaobluesky

在此基礎(chǔ)上,如果在查詢鎖表時,對不存在ID進(jìn)行Insert操作,將導(dǎo)致等待阻塞。

額外的鎖

除了DB本身分類外,在框架層面,還有樂觀鎖與悲觀鎖之分。注意層面,這種鎖屬于應(yīng)用程序設(shè)計的鎖,而非數(shù)據(jù)庫設(shè)計的鎖。

以我最熟悉的Yii 2框架為例。簡述:

樂觀鎖就是一個可對比序列號,但存在高頻并發(fā)時的對比錯位 BUG;

悲觀鎖就是一個嚴(yán)謹(jǐn)可對比序列號,并提供解鎖功能。事實上,由于悲觀鎖的使用復(fù)雜度(我沒看出來),Yii 2并沒有提供悲觀鎖功能。

解鎖

說完鎖,我們肯定需要一個解鎖機制,腦海里忽然蹦出冷段子:一人去買門鎖,安好了才發(fā)現(xiàn),這門只能從外面開,進(jìn)去鎖門就出不來了。

很冷吧。沒有解鎖機制的事務(wù)處理系統(tǒng),是一個只能進(jìn),不能出的事務(wù)處理系統(tǒng)——死鎖盡管會自動解鎖,但反饋時間是一個很剛性的設(shè)置。

先說這個很剛的設(shè)置,如果你想修改它,可以去 my.ini 文件的innodb_lock_wait_timeout這一行,默認(rèn)為50
s的等待時間。

應(yīng)用層面的鎖可以通過校對序列號來自行解鎖,而MySQL層面的鎖,可以通過information_schemePROCESSLIST表,來完成解鎖——確認(rèn)無法完成事務(wù)。

這里說一下PROCESSLIST表,當(dāng)一個關(guān)閉自動提交的事務(wù)已經(jīng)啟動,另一個同類事務(wù)也啟動,雙方?jīng)_突后,在這個表內(nèi)是存在沖突SQL Status,你可以自己去觀察。

最后:無論解鎖機制多么健全,死鎖本身是代碼邏輯引起的,不修正/優(yōu)化代碼邏輯,單純的解鎖機制不過是對系統(tǒng)的額外負(fù)擔(dān)。

解決方案很簡單:自己寫一個簡單的Log功能,將所有觸發(fā)解鎖機制的情況,記錄在Log里,自行優(yōu)化。

隔離

配合鎖機制的就是隔離機制,它可以盡可能有效的設(shè)置:事務(wù)間的可見度。

讀取未提交(RU,Read Uncommitted):最低隔離,問題是臟讀(未被提交的UPDATE,仍然可被讀取)。

讀取提交(RC,Read Committed):語句提交以后即執(zhí)行了COMMIT以后別的事務(wù)就能讀到這個改變. 問題:不可重復(fù)讀(同事務(wù)時,前后讀取到不一致數(shù)據(jù))。

可重復(fù)讀(RR,Repeatable Read):在同一個事務(wù)里面先后執(zhí)行同一個查詢語句的時候,得到的結(jié)果是一樣的,問題:幻讀(并發(fā)事務(wù)同時處理同內(nèi)容,并導(dǎo)致一方內(nèi)容覆蓋了另一方,令對方感覺出現(xiàn)了幻覺)。

序列化(S,Serializable):在這個級別下,所有的事務(wù)的完整性都被保留,意味著所有的事務(wù)都可以被序列化的執(zhí)行,只有當(dāng)兩個事務(wù)之間沒有任務(wù)沖突時,才能并發(fā)的執(zhí)行。

四個級別中,高級隔離不會遇到比自己低級隔離的問題,但隔離級別越高,對并發(fā)的損失性越高。

MySQL默認(rèn)采用RR級別。

題外

提到鎖,就想到以前做過的秒殺后端,當(dāng)時的處理機制很簡單,時間戳 + 事務(wù)。

時光荏苒,現(xiàn)在回頭看,忽然發(fā)現(xiàn)有一些改進(jìn)的地方,一筆帶過:秒殺最大數(shù)量 緩存對比 → 服務(wù)器端 微秒級時間戳 + 事務(wù)/悲觀鎖 插入 + 插入失敗 緩存隊列及二次插入嘗試,這樣已經(jīng)能夠解決極大程度的并發(fā)問題了。

如果這樣都會出現(xiàn)重復(fù)插入問題,那按我目前的水準(zhǔn),在應(yīng)用層面是解決不了了。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/23213.html

相關(guān)文章

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<