數(shù)據(jù)庫(kù)事務(wù)和鎖

數(shù)據(jù)庫(kù)的事務(wù)
什么是數(shù)據(jù)庫(kù)的事務(wù)谴古?
數(shù)據(jù)庫(kù)事務(wù)(transaction)是訪問并發(fā)可能操作各種數(shù)據(jù)項(xiàng)的一個(gè)數(shù)據(jù)庫(kù)操作序列掰担,這次操作要么全部執(zhí)行带饱,要么全部不執(zhí)行,是一個(gè)不可分割的工作單位勺疼,事務(wù)由事務(wù)開始與事務(wù)結(jié)束之間執(zhí)行的全書數(shù)據(jù)庫(kù)操作組成捏鱼。

事務(wù)的四大特性是什么穷躁?
原子性:原子性是指包含事務(wù)的操作要么全部執(zhí)行成功问潭,要么全部失敗回滾狡忙。
一致性:一致性是指事務(wù)在執(zhí)行前后狀態(tài)是一致的
隔離性:一個(gè)事務(wù)進(jìn)行的修改在最終提交之前灾茁,對(duì)其他的事務(wù)是不可見的
持久性: 數(shù)據(jù)一旦提交,其所作的修改將永久地保存在數(shù)據(jù)庫(kù)中

數(shù)據(jù)庫(kù)并發(fā)的一致性問題禀挫?
當(dāng)多個(gè)事務(wù)并發(fā)執(zhí)行時(shí)语婴,可能會(huì)出現(xiàn)以下問題:
臟讀:事務(wù)A更新了數(shù)據(jù)砰左,但還沒有提交场航,這時(shí)事務(wù)B讀取到事務(wù)A更新后的數(shù)據(jù)溉痢,然后事務(wù)A回滾了适室,事務(wù)B讀取到的數(shù)據(jù)就成為了臟數(shù)據(jù)。
不可重復(fù)讀:事務(wù)A對(duì)數(shù)據(jù)進(jìn)行多次讀取蔬螟,事務(wù)B在事務(wù)A多次讀取的過程中執(zhí)行了更新操作并提交了旧巾,導(dǎo)致事務(wù)A多次讀取到的數(shù)據(jù)并不一致鲁猩。
幻讀:事務(wù)A在讀取數(shù)據(jù)后罢坝,事務(wù)B向事務(wù)A讀取的數(shù)據(jù)中插入了幾條數(shù)據(jù),事務(wù)A再次讀取數(shù)據(jù)時(shí)發(fā)現(xiàn)多了幾條數(shù)據(jù)男应,和之前讀取的數(shù)據(jù)不一致

數(shù)據(jù)庫(kù)的隔離級(jí)別有哪些沐飘?
未提交讀:一個(gè)事務(wù)在提交前牲迫,他的修改對(duì)其他事務(wù)是可見的
提交讀:一個(gè)事務(wù)提交之后盹憎,他的修改才能被其他事務(wù)看到
可重復(fù)讀: 在同一個(gè)事務(wù)中多次讀取到的數(shù)據(jù)是一致的
串行化:需要加鎖實(shí)現(xiàn),會(huì)強(qiáng)制事務(wù)串行執(zhí)行

隔離級(jí)別 臟讀 不可重復(fù)讀 幻讀
未提交讀 允許 允許 允許
提交讀 不允許 允許 允許
可重復(fù)讀 不允許 不允許 允許
串行化 不允許 不允許 不允許

mysql 默認(rèn)的隔離級(jí)別是 可重復(fù)讀

隔離級(jí)別是如何實(shí)現(xiàn)的?
事務(wù)的隔離機(jī)制主要是依靠鎖機(jī)制和MVCC(多版本并發(fā)控制)實(shí)現(xiàn)的奶稠,提交讀和可重復(fù)讀可以通過MVCC實(shí)現(xiàn)锌订,串行化可以通過鎖機(jī)制實(shí)現(xiàn)

什么是MVCC?
MVCC( multiple version concurrent control )是一種控制并發(fā)的方法啦辐,主要用來提高數(shù)據(jù)庫(kù)的并發(fā)性能

在了解MVCC時(shí)應(yīng)該先了解當(dāng)前讀和快照讀
當(dāng)前讀:讀取的是數(shù)據(jù)庫(kù)的最新版本芹关,并且在讀取時(shí)保證其他事務(wù)不會(huì)修改當(dāng)前的記錄侥衬,所以會(huì)對(duì)讀取的數(shù)據(jù)加鎖跑芳。
快照讀:不加鎖的讀取操作即為快照讀博个,使用MVCC來讀取快照中的數(shù)據(jù),避免加鎖帶來的性能損耗

可以看到MVCC的作用是在不加鎖的情況下往堡,解決數(shù)據(jù)讀寫沖突問題,并且解決臟讀养葵、幻讀、不可重復(fù)讀等問題佃蚜,但是不能解決丟失修改問題谐算。

MVCC的實(shí)現(xiàn)原理:
版本號(hào):
系統(tǒng)版本號(hào):是一個(gè)自增的ID,每開啟一個(gè)事務(wù)斤儿,系統(tǒng)版本號(hào)都會(huì)自增
事務(wù)版本號(hào):事務(wù)版本號(hào)就是事務(wù)開始時(shí)的系統(tǒng)版本號(hào)往果,可以通過事務(wù)版本號(hào)的大小判斷事務(wù)的時(shí)間順序
行記錄隱藏的列
DB_ROW_ID:所需空軍6byte陕贮,隱含的自增ID潘飘,用來生產(chǎn)聚簇索引,如果數(shù)據(jù)表沒有指定的聚簇索引戈擒,InnoDB會(huì)利用這個(gè)隱藏的id 創(chuàng)建聚簇索引
DB_TRX_ID:所需空間6byte,最近修改的事務(wù)ID筐高,記錄創(chuàng)建這條記錄或最后一次修改這條記錄的事務(wù)ID
DB_Roll_PTR: 所需空間7byte,回滾指針现喳,指向這條記錄的上一個(gè)版本

undo日志
mvcc做使用到的快照會(huì)存儲(chǔ)到Undo日志中,該日志通過回滾指針將一個(gè)一個(gè)數(shù)據(jù)行的所有快照連接起來冰单。

在重復(fù)讀的隔離級(jí)別下诫欠,innodb的工作流程:
SELECT
作為查詢結(jié)果要滿足兩個(gè)條件:
當(dāng)前事務(wù)所要查詢的數(shù)據(jù)行快照的創(chuàng)建版本號(hào)必須小于當(dāng)前事務(wù)的版本號(hào),這樣做的目的是保證當(dāng)前事務(wù)讀取的數(shù)據(jù)行的快照要么在當(dāng)前事務(wù)開始前就已經(jīng)存在轿偎,要么就是當(dāng)前事務(wù)自身插入或者修改過的
當(dāng)前事務(wù)所要讀取的數(shù)據(jù)行快照的刪除版本號(hào)必須大雨當(dāng)前事務(wù)的版本號(hào)被廓,如果是小于等于的話嫁乘,表示該數(shù)據(jù)行快照已經(jīng)被刪除,不能讀取
INSERT
將當(dāng)前系統(tǒng)版本號(hào)作為數(shù)據(jù)行快照的創(chuàng)建版本號(hào)
DELETE
將當(dāng)前系統(tǒng)版本號(hào)作為數(shù)據(jù)行快照的刪除版本號(hào)
UPDATE
保存當(dāng)前系統(tǒng)版本號(hào)為更新前數(shù)據(jù)行快照創(chuàng)建的行版本號(hào)仓蛆,并保存當(dāng)前系統(tǒng)版本號(hào)為更新后的數(shù)據(jù)行快照的刪除版本號(hào)看疙,其實(shí)就是能庆,先刪除在插入即為更新

總計(jì)一下,MVCC的作用就是在避免枷鎖的情況下相味,最大限度的解決讀寫并發(fā)沖突的問題丰涉,他可以實(shí)現(xiàn)提交讀和可重復(fù)讀的兩個(gè)隔離級(jí)一死。

數(shù)據(jù)庫(kù)的鎖

什么是數(shù)據(jù)庫(kù)的鎖傻唾?

當(dāng)數(shù)據(jù)庫(kù)有并發(fā)事務(wù)的時(shí)候,保證數(shù)據(jù)訪問順序的機(jī)制稱之為鎖機(jī)制
數(shù)據(jù)庫(kù)的鎖與隔離級(jí)別的關(guān)系伪煤?
隔離級(jí)別 實(shí)現(xiàn)方式
未提交讀 總是讀取最新的數(shù)據(jù)抱既,無需加鎖
提交讀 讀取數(shù)據(jù)時(shí)加共享鎖扁誓,讀取數(shù)據(jù)后釋放共享鎖
可重復(fù)讀 讀取數(shù)據(jù)時(shí)加共享鎖,事務(wù)結(jié)束后釋放共享鎖
串行化 鎖定整個(gè)范圍健足删,一直持有鎖到事務(wù)結(jié)束

數(shù)據(jù)庫(kù)鎖的類型有哪些失受?
按照鎖的粒度可以將mysql鎖分為三種:

mysql 鎖級(jí)別 資源開銷 加速鎖速度 是否會(huì)出現(xiàn)死鎖 鎖的粒度 并發(fā)度

表級(jí)鎖 小 快 不會(huì) 大 低

行級(jí)鎖 大 慢 會(huì) 小 高

頁(yè)面鎖 一般 一般 不會(huì) 一般 一般

Myisam 默認(rèn)采用表級(jí)鎖贱纠,innoDB默認(rèn)采用行級(jí)鎖
從鎖的類別上區(qū)別可以分為共享鎖和排他鎖

共享鎖:共享鎖又稱讀鎖响蕴,簡(jiǎn)稱為S鎖浦夷,一個(gè)事務(wù)對(duì)一個(gè)數(shù)據(jù)對(duì)象加了S鎖辜王,可以對(duì)這個(gè)對(duì)象進(jìn)行讀去操作呐馆,但不能進(jìn)行更新操作,并且在加鎖期間其他事務(wù)只能對(duì)這個(gè)數(shù)據(jù)對(duì)象加S鎖续膳,不能加X鎖收班。
排他鎖:排他鎖又稱為寫鎖,簡(jiǎn)稱X鎖社付,一個(gè)事務(wù)對(duì)一個(gè)數(shù)據(jù)對(duì)象加了X鎖邻耕,可以對(duì)這個(gè)對(duì)象進(jìn)行讀取和更新操作兄世,加鎖期間碘饼,其他事務(wù)不能對(duì)該數(shù)據(jù)對(duì)象晉西加X鎖或S鎖

mysql 中InnoDB 引擎的行鎖模式及其是如何實(shí)現(xiàn)的

行鎖模式

在存在行鎖和表鎖的情況下悲伶,一個(gè)事務(wù)想對(duì)某個(gè)表加X鎖時(shí)麸锉,需要先檢查是否有其他事務(wù)對(duì)這個(gè)表加了鎖或?qū)@個(gè)表的某一行加了鎖花沉,對(duì)表的每一行都進(jìn)行檢測(cè)一次是非常低效率的碱屁,為了解決這種問題蛾找,實(shí)現(xiàn)多粒度鎖機(jī)制打毛,InnDB還有兩種內(nèi)部使用的意向鎖幻枉,兩種意向鎖都是表鎖。
意向共享鎖:簡(jiǎn)稱IS鎖胰挑,一個(gè)事務(wù)打算給數(shù)據(jù)行加共享鎖前必須先獲得該表的IS鎖
意向排他鎖:簡(jiǎn)稱IX鎖瞻颂,一個(gè)事務(wù)打算給數(shù)據(jù)行加排他鎖前必須先獲得該表的IX鎖

有了意向鎖蘸朋,一個(gè)事務(wù)想對(duì)某個(gè)表加X鎖藕坯,只要檢查是否有其他事務(wù)對(duì)這個(gè)表加了X/IX/S/IS鎖即可噪沙。

行鎖的實(shí)現(xiàn)方式:INnDB 行鎖主要分三種情況:
對(duì)索引加鎖
對(duì)索引之間的間隙正歼,第一條記錄前的間隙或最后一條后的間隙加鎖
前兩中放入組合局义,對(duì)記錄及前面的間隙枷鎖
innoDB 行鎖的特性:如果不通過索引條件檢索數(shù)據(jù)喜爷,那么innoDB將對(duì)表中所有記錄加鎖,實(shí)際產(chǎn)生的效果和表鎖一樣
MVCC不能解決幻讀問題术幔,在可重復(fù)讀隔離級(jí)別下诅挑,使用MVCC +Next-key Locks可以解決幻讀問題

什么是數(shù)據(jù)庫(kù)的樂觀鎖和悲觀鎖拔妥,如何實(shí)現(xiàn)没龙?

樂觀鎖兜畸;系統(tǒng)假設(shè)數(shù)據(jù)的更新在大多數(shù)時(shí)候不會(huì)產(chǎn)生沖突的,所以數(shù)據(jù)庫(kù)只在更新數(shù)據(jù)操作提交的時(shí)候?qū)?shù)據(jù)檢測(cè)沖突煞躬,如果存在沖突恩沛,則更新數(shù)據(jù)失敗

樂觀鎖實(shí)現(xiàn)方式:一般通過版本號(hào)和CAS 算法實(shí)現(xiàn)

悲觀鎖:假定會(huì)發(fā)生沖突雷客,屏蔽一切可能違反數(shù)據(jù)完整性的操作搅裙,通俗講就是每次去拿數(shù)據(jù)的時(shí)候都認(rèn)為別人會(huì)修改部逮,所以每次都在拿數(shù)據(jù)的時(shí)候都會(huì)上鎖兄朋。

悲觀鎖的實(shí)現(xiàn)方式: 通過數(shù)據(jù)庫(kù)的鎖機(jī)制實(shí)現(xiàn),對(duì)查詢語(yǔ)句添加 for updata

什么死鎖怜械?如何避免颅和?

死鎖是指兩個(gè)或者兩個(gè)以上的進(jìn)程在執(zhí)行過程中傅事,由于競(jìng)爭(zhēng)資源或者由于彼此通信而早造成的一種阻塞現(xiàn)象,在mysql 中峡扩,Myisam是一次獲取所需的全部鎖蹭越,要么全部滿足,要么全部等待有额,所以不會(huì)出現(xiàn)死鎖般又。在Innodb存儲(chǔ)引擎中,除了三個(gè)SQL組成的事務(wù)外巍佑,鎖都是逐步獲得的茴迁,所以存在死鎖的問題。

如何避免mysql 發(fā)生死鎖或鎖沖突萤衰?

    如果不通的程序并發(fā)存取多個(gè)表,盡量以相同的順序訪問表
    在程序以批量方式處理數(shù)據(jù)的時(shí)候怕膛,如果已經(jīng)對(duì)數(shù)據(jù)排序椅邓,盡量保證每個(gè)縣城按照固定的順序來處理記錄
    在事務(wù)中,如果需要更新記錄,應(yīng)直接申請(qǐng)足夠級(jí)別的排他鎖茬底,而不應(yīng)該先申請(qǐng)共享鎖,更新時(shí)在申請(qǐng)排他鎖,因?yàn)樵诋?dāng)前用戶申請(qǐng)排他鎖時(shí),其他事務(wù)可能已經(jīng)獲得了相同記錄的共享鎖帮坚,從而造成鎖沖突或者死鎖纫普。
    盡量使用較低的隔離級(jí)別
    盡量使用索引訪問數(shù)據(jù),是加鎖更加準(zhǔn)確,從而減少鎖沖突的機(jī)會(huì)
    合理選擇事務(wù)的大小,小事務(wù)發(fā)生鎖沖突的概率更低
    盡量用相等的條件訪問數(shù)據(jù),可以避免Next-key 鎖對(duì)并發(fā)插入的影響
    不要申請(qǐng)超過十幾需要的鎖級(jí)別,查詢時(shí)盡量不顯示加鎖
    對(duì)于一些特定的事務(wù),可以表鎖來提高處理速度或減少死鎖的概率
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末尚困,一起剝皮案震驚了整個(gè)濱河市谬泌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件分苇,死亡現(xiàn)場(chǎng)離奇詭異蘑斧,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門域携,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人拆内,你說我怎么就攤上這事。” “怎么了卦羡?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵刺桃,是天一觀的道長(zhǎng)葛碧。 經(jīng)常有香客問我,道長(zhǎng)廓推,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮梁丘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘悔政。我一直安慰自己,他們只是感情好祷愉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布杨拐。 她就那樣靜靜地躺著,像睡著了一般敢课。 火紅的嫁衣襯著肌膚如雪齿诉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天馋记,我揣著相機(jī)與錄音畜隶,去河邊找鬼籽慢。 笑死箱亿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起液茎,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤逞姿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后捆等,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體滞造,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年栋烤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了谒养。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡明郭,死狀恐怖蝴光,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情达址,我是刑警寧澤蔑祟,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站沉唠,受9級(jí)特大地震影響疆虚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜满葛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一径簿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧嘀韧,春花似錦篇亭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至谊却,卻和暖如春柔昼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背炎辨。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工捕透, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓乙嘀,卻偏偏與公主長(zhǎng)得像末购,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子虎谢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容