电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術(shù)文章
文章詳情頁

詳解MySQL中事務(wù)隔離級別的實現(xiàn)原理

瀏覽:3日期:2023-10-06 12:55:54
前言

說到數(shù)據(jù)庫事務(wù),大家腦子里一定很容易蹦出一堆事務(wù)的相關(guān)知識,如事務(wù)的ACID特性,隔離級別,解決的問題(臟讀,不可重復讀,幻讀)等等,但是可能很少有人真正的清楚事務(wù)的這些特性又是怎么實現(xiàn)的,為什么要有四個隔離級別。

今天我們就先來聊聊MySQL中事務(wù)的隔離性的實現(xiàn)原理,后續(xù)還會繼續(xù)出文章分析其他特性的實現(xiàn)原理。

當然MySQL博大精深,文章疏漏之處在所難免,歡迎批評指正。

說明

MySQL的事務(wù)實現(xiàn)邏輯是位于引擎層的,并且不是所有的引擎都支持事務(wù)的,下面的說明都是以InnoDB引擎為基準。

定義

隔離性(isolation)指的是不同事務(wù)先后提交并執(zhí)行后,最終呈現(xiàn)出來的效果是串行的,也就是說,對于事務(wù)來說,它在執(zhí)行過程中,感知到的數(shù)據(jù)變化應(yīng)該只有自己操作引起的,不存在其他事務(wù)引發(fā)的數(shù)據(jù)變化。

隔離性解決的是并發(fā)事務(wù)出現(xiàn)的問題。

標準SQL隔離級別

隔離性最簡單的實現(xiàn)方式就是各個事務(wù)都串行執(zhí)行了,如果前面的事務(wù)還沒有執(zhí)行完畢,后面的事務(wù)就都等待。但是這樣的實現(xiàn)方式很明顯并發(fā)效率不高,并不適合在實際環(huán)境中使用。

為了解決上述問題,實現(xiàn)不同程度的并發(fā)控制,SQL的標準制定者提出了不同的隔離級別:未提交讀(read uncommitted)、提交讀(read committed)、可重復讀(repeatable read)、序列化讀(serializable)。其中最高級隔離級別就是序列化讀,而在其他隔離級別中,由于事務(wù)是并發(fā)執(zhí)行的,所以或多或少允許出現(xiàn)一些問題。見以下的矩陣表:

隔離級別(+:允許出現(xiàn),-:不允許出現(xiàn)) 臟讀 不可重復讀 幻讀 未提交讀 + + + 提交讀 - + + 可重復讀 - - + 序列化讀 - - -

注意,MySQL的InnoDB引擎在提交讀級別通過MVCC解決了不可重復讀的問題,在可重復讀級別通過間隙鎖解決了幻讀問題,具體見下面的分析。

實現(xiàn)原理標準SQL事務(wù)隔離級別實現(xiàn)原理

我們上面遇到的問題其實就是并發(fā)事務(wù)下的控制問題,解決并發(fā)事務(wù)的最常見方式就是悲觀并發(fā)控制了(也就是數(shù)據(jù)庫中的鎖)。標準SQL事務(wù)隔離級別的實現(xiàn)是依賴鎖的,我們來看下具體是怎么實現(xiàn)的:

事務(wù)隔離級別 實現(xiàn)方式 未提交讀(RU) 事務(wù)對當前被讀取的數(shù)據(jù)不加鎖; 事務(wù)在更新某數(shù)據(jù)的瞬間(就是發(fā)生更新的瞬間),必須先對其加行級共享鎖,直到事務(wù)結(jié)束才釋放。 提交讀(RC) 事務(wù)對當前被讀取的數(shù)據(jù)加行級共享鎖(當讀到時才加鎖),一旦讀完該行,立即釋放該行級共享鎖; 事務(wù)在更新某數(shù)據(jù)的瞬間(就是發(fā)生更新的瞬間),必須先對其加行級排他鎖,直到事務(wù)結(jié)束才釋放。 可重復讀(RR) 事務(wù)在讀取某數(shù)據(jù)的瞬間(就是開始讀取的瞬間),必須先對其加行級共享鎖,直到事務(wù)結(jié)束才釋放; 事務(wù)在更新某數(shù)據(jù)的瞬間(就是發(fā)生更新的瞬間),必須先對其加行級排他鎖,直到事務(wù)結(jié)束才釋放。 序列化讀(S)事務(wù)在讀取數(shù)據(jù)時,必須先對其加表級共享鎖 ,直到事務(wù)結(jié)束才釋放; 事務(wù)在更新數(shù)據(jù)時,必須先對其加表級排他鎖 ,直到事務(wù)結(jié)束才釋放。

可以看到,在只使用鎖來實現(xiàn)隔離級別的控制的時候,需要頻繁的加鎖解鎖,而且很容易發(fā)生讀寫的沖突(例如在RC級別下,事務(wù)A更新了數(shù)據(jù)行1,事務(wù)B則在事務(wù)A提交前讀取數(shù)據(jù)行1都要等待事務(wù)A提交并釋放鎖)。

為了不加鎖解決讀寫沖突的問題,MySQL引入了MVCC機制,詳細可見我以前的分析文章:一文讀懂數(shù)據(jù)庫中的樂觀鎖和悲觀鎖和MVCC。

InnoDB事務(wù)隔離級別實現(xiàn)原理

在往下分析之前,我們有幾個概念需要先了解下:

1、鎖定讀和一致性非鎖定讀

鎖定讀:在一個事務(wù)中,主動給讀加鎖,如SELECT ... LOCK IN SHARE MODE 和 SELECT ... FOR UPDATE。分別加上了行共享鎖和行排他鎖。鎖的分類可見我以前的分析文章:你應(yīng)該了解的MySQL鎖分類)。

https://dev.mysql.com/doc/refman/8.0/en/innodb-locking-reads.html

一致性非鎖定讀:InnoDB使用MVCC向事務(wù)的查詢提供某個時間點的數(shù)據(jù)庫快照。查詢會看到在該時間點之前提交的事務(wù)所做的更改,而不會看到稍后或未提交的事務(wù)所做的更改(本事務(wù)除外)。也就是說在開始了事務(wù)之后,事務(wù)看到的數(shù)據(jù)就都是事務(wù)開啟那一刻的數(shù)據(jù)了,其他事務(wù)的后續(xù)修改不會在本次事務(wù)中可見。

Consistent read是InnoDB在RC和RR隔離級別處理SELECT語句的默認模式。一致性非鎖定讀不會對其訪問的表設(shè)置任何鎖,因此,在對表執(zhí)行一致性非鎖定讀的同時,其它事務(wù)可以同時并發(fā)的讀取或者修改它們。

https://dev.mysql.com/doc/refman/8.0/en/innodb-consistent-read.html

2、當前讀和快照讀

當前讀

讀取的是最新版本,像UPDATE、DELETE、INSERT、SELECT ... LOCK IN SHARE MODE、SELECT ... FOR UPDATE這些操作都是一種當前讀,為什么叫當前讀?就是它讀取的是記錄的最新版本,讀取時還要保證其他并發(fā)事務(wù)不能修改當前記錄,會對讀取的記錄進行加鎖。

快照讀

讀取的是快照版本,也就是歷史版本,像不加鎖的SELECT操作就是快照讀,即不加鎖的非阻塞讀;快照讀的前提是隔離級別不是未提交讀和序列化讀級別,因為未提交讀總是讀取最新的數(shù)據(jù)行,而不是符合當前事務(wù)版本的數(shù)據(jù)行,而序列化讀則會對表加鎖。

3、隱式鎖定和顯式鎖定

隱式鎖定

InnoDB在事務(wù)執(zhí)行過程中,使用兩階段鎖協(xié)議(不主動進行顯示鎖定的情況):

隨時都可以執(zhí)行鎖定,InnoDB會根據(jù)隔離級別在需要的時候自動加鎖; 鎖只有在執(zhí)行commit或者rollback的時候才會釋放,并且所有的鎖都是在同一時刻被釋放。

顯式鎖定

InnoDB也支持通過特定的語句進行顯示鎖定(存儲引擎層)

select ... lock in share mode //共享鎖select ... for update //排他鎖 MySQL Server層的顯示鎖定:

lock tableunlock table

了解完上面的概念后,我們來看下InnoDB的事務(wù)具體是怎么實現(xiàn)的(下面的讀都指的是非主動加鎖的select)

事務(wù)隔離級別 實現(xiàn)方式 未提交讀(RU) 事務(wù)對當前被讀取的數(shù)據(jù)不加鎖,都是當前讀; 事務(wù)在更新某數(shù)據(jù)的瞬間(就是發(fā)生更新的瞬間),必須先對其加行級共享鎖,直到事務(wù)結(jié)束才釋放。 提交讀(RC) 事務(wù)對當前被讀取的數(shù)據(jù)不加鎖,且是快照讀; 事務(wù)在更新某數(shù)據(jù)的瞬間(就是發(fā)生更新的瞬間),必須先對其加行級排他鎖(Record),直到事務(wù)結(jié)束才釋放。 通過快照,在這個級別MySQL就解決了不可重復讀的問題 可重復讀(RR) 事務(wù)對當前被讀取的數(shù)據(jù)不加鎖,且是快照讀; 事務(wù)在更新某數(shù)據(jù)的瞬間(就是發(fā)生更新的瞬間),必須先對其加行級排他鎖(Record,GAP,Next-Key),直到事務(wù)結(jié)束才釋放。 通過間隙鎖,在這個級別MySQL就解決了幻讀的問題 序列化讀(S)事務(wù)在讀取數(shù)據(jù)時,必須先對其加表級共享鎖 ,直到事務(wù)結(jié)束才釋放,都是當前讀; 事務(wù)在更新數(shù)據(jù)時,必須先對其加表級排他鎖 ,直到事務(wù)結(jié)束才釋放。

可以看到,InnoDB通過MVCC很好的解決了讀寫沖突的問題,而且提前一個級別就解決了標準級別下會出現(xiàn)的幻讀和不可重復讀問題,大大提升了數(shù)據(jù)庫的并發(fā)能力。

一些常見誤區(qū)幻讀到底包不包括了delete的情況?

不可重復讀:前后多次讀取一行,數(shù)據(jù)內(nèi)容不一致,針對其他事務(wù)的update和delete操作。為了解決這個問題,使用行共享鎖,鎖定到事務(wù)結(jié)束(也就是RR級別,當然MySQL使用MVCC在RC級別就解決了這個問題)

幻讀:當同一個查詢在不同時間生成不同的行集合時就是出現(xiàn)了幻讀,針對的是其他事務(wù)的insert操作,為了解決這個問題,鎖定整個表到事務(wù)結(jié)束(也就是S級別,當然MySQL使用間隙鎖在RR級別就解決了這個問題)

網(wǎng)上很多文章提到幻讀和提交讀的時候,有的說幻讀包括了delete的情況,有的說delete應(yīng)該屬于提交讀的問題,那到底真相如何呢?我們實際來看下MySQL的官方文檔(如下)

The so-called phantom problem occurs within a transaction when the same query produces different sets of rows at different times. For example, if a SELECT) is executed twice, but returns a row the second time that was not returned the first time, the row is a “phantom” row.https://dev.mysql.com/doc/refman/5.7/en/innodb-next-key-locking.html

可以看到,幻讀針對的是結(jié)果集前后發(fā)生變化,所以看起來delete的情況應(yīng)該歸為幻讀,但是我們實際分析下上面列出的標準SQL在RR級別的實現(xiàn)原理就知道,標準SQL的RR級別是會對查到的數(shù)據(jù)行加行共享鎖,所以這時候其他事務(wù)想刪除這些數(shù)據(jù)行其實是做不到的,所以在RR下,不會出現(xiàn)因delete而出現(xiàn)幻讀現(xiàn)象,也就是幻讀不包含delete的情況。

MVCC能解決了幻讀問題?

網(wǎng)上很多文章會說MVCC或者MVCC+間隙鎖解決了幻讀問題,實際上MVCC并不能解決幻讀問題。如以下的例子:

begin;#假設(shè)users表為空,下面查出來的數(shù)據(jù)為空select * from users; #沒有加鎖#此時另一個事務(wù)提交了,且插入了一條id=1的數(shù)據(jù)select * from users; #讀快照,查出來的數(shù)據(jù)為空update users set name=’mysql’ where id=1;#update是當前讀,所以更新成功,并生成一個更新的快照select * from users; #讀快照,查出來id為1的一條記錄,因為MVCC可以查到當前事務(wù)生成的快照commit;

可以看到前后查出來的數(shù)據(jù)行不一致,發(fā)生了幻讀。所以說只有MVCC是不能解決幻讀問題的,解決幻讀問題靠的是間隙鎖。如下:

begin;#假設(shè)users表為空,下面查出來的數(shù)據(jù)為空select * from users lock in share mode; #加上共享鎖#此時另一個事務(wù)B想提交且插入了一條id=1的數(shù)據(jù),由于有間隙鎖,所以要等待select * from users; #讀快照,查出來的數(shù)據(jù)為空update users set name=’mysql’ where id=1;#update是當前讀,由于不存在數(shù)據(jù),不進行更新select * from users; #讀快照,查出來的數(shù)據(jù)為空commit;#事務(wù)B提交成功并插入數(shù)據(jù)

注意,RR級別下想解決幻讀問題,需要我們顯式加鎖,不然查詢的時候還是不會加鎖的

以上就是詳解MySQL中事務(wù)隔離級別的實現(xiàn)原理的詳細內(nèi)容,更多關(guān)于MySQL 事務(wù)隔離級別的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

相關(guān)文章:
主站蜘蛛池模板: 电竞学校_电子竞技培训学校学院-梦竞未来电竞学校官网 | 珠海网站建设_响应网站建设_珠海建站公司_珠海网站设计与制作_珠海网讯互联 | 卫生纸复卷机|抽纸机|卫生纸加工设备|做卫生纸机器|小型卫生纸加工需要什么设备|卫生纸机器设备多少钱一台|许昌恒源纸品机械有限公司 | 辽宁资质代办_辽宁建筑资质办理_辽宁建筑资质延期升级_辽宁中杭资质代办 | 蜘蛛车-高空作业平台-升降机-高空作业车租赁-臂式伸缩臂叉装车-登高车出租厂家 - 普雷斯特机械设备(北京)有限公司 | 净化工程_无尘车间_无尘车间装修-广州科凌净化工程有限公司 | 一体化污水处理设备,一体化污水设备厂家-宜兴市福源水处理设备有限公司 | ASA膜,ASA共挤料,篷布色母料-青岛未来化学有限公司 | 硫化罐_蒸汽硫化罐_大型硫化罐-山东鑫泰鑫智能装备有限公司 | 高柔性拖链电缆_卷筒电缆_耐磨耐折聚氨酯电缆-玖泰特种电缆 | 不锈钢搅拌罐_高速搅拌罐厂家-无锡市凡格德化工装备科技有限公司 | 依维柯自动挡房车,自行式国产改装房车,小型房车价格,中国十大房车品牌_南京拓锐斯特房车 - 南京拓锐斯特房车 | 除甲醛公司-甲醛检测治理-杭州创绿家环保科技有限公司-室内空气净化十大品牌 | 新型游乐设备,360大摆锤游乐设备「诚信厂家」-山东方鑫游乐设备 新能源汽车电池软连接,铜铝复合膜柔性连接,电力母排-容发智能科技(无锡)有限公司 | 肉嫩度仪-凝胶测试仪-国产质构仪-气味分析仪-上海保圣实业发展有限公司|总部 | Trimos测长机_测高仪_TESA_mahr,WYLER水平仪,PWB对刀仪-德瑞华测量技术(苏州)有限公司 | 光泽度计_测量显微镜_苏州压力仪_苏州扭力板手维修-苏州日升精密仪器有限公司 | 接地电阻测试仪[厂家直销]_电缆故障测试仪[精准定位]_耐压测试仪-武汉南电至诚电力设备 | 低温柔性试验仪-土工布淤堵-沥青车辙试验仪-莱博特(天津)试验机有限公司 | 丙烷/液氧/液氮气化器,丙烷/液氧/液氮汽化器-无锡舍勒能源科技有限公司 | loft装修,上海嘉定酒店式公寓装修公司—曼城装饰 | 细砂提取机,隔膜板框泥浆污泥压滤机,螺旋洗砂机设备,轮式洗砂机械,机制砂,圆锥颚式反击式破碎机,振动筛,滚筒筛,喂料机- 上海重睿环保设备有限公司 | EPK超声波测厚仪,德国EPK测厚仪维修-上海树信仪器仪表有限公司 | 天津试验仪器-电液伺服万能材料试验机,恒温恒湿标准养护箱,水泥恒应力压力试验机-天津鑫高伟业科技有限公司 | 没斑啦-专业的祛斑美白嫩肤知识网站-去斑经验分享 | 实验室装修_实验室设计_实验室规划设计- 上海广建净化工程公司 | 冷轧机|两肋冷轧机|扁钢冷轧机|倒立式拉丝机|钢筋拔丝机|收线机-巩义市华瑞重工机械制造有限公司 | 希望影视-高清影视vip热播电影电视剧免费在线抢先看 | 挤塑板-XPS挤塑板-挤塑板设备厂家[襄阳欧格] | 超声波成孔成槽质量检测仪-压浆机-桥梁预应力智能张拉设备-上海硕冠检测设备有限公司 | 刑事律师_深圳著名刑事辩护律师_王平聚【清华博士|刑法教授】 | 卫生纸复卷机|抽纸机|卫生纸加工设备|做卫生纸机器|小型卫生纸加工需要什么设备|卫生纸机器设备多少钱一台|许昌恒源纸品机械有限公司 | 深圳美安可自动化设备有限公司,喷码机,定制喷码机,二维码喷码机,深圳喷码机,纸箱喷码机,东莞喷码机 UV喷码机,日期喷码机,鸡蛋喷码机,管芯喷码机,管内壁喷码机,喷码机厂家 | 水质监测站_水质在线分析仪_水质自动监测系统_多参数水质在线监测仪_水质传感器-山东万象环境科技有限公司 | 冷却塔减速机器_冷却塔皮带箱维修厂家_凉水塔风机电机更换-广东康明冷却塔厂家 | 洁净实验室工程-成都手术室净化-无尘车间装修-四川华锐净化公司-洁净室专业厂家 | 活性炭-果壳木质煤质柱状粉状蜂窝活性炭厂家价格多少钱 | 液压升降平台_剪叉式液压/导轨式升降机_传菜机定做「宁波日腾升降机厂家」 | 硅胶管挤出机厂家_硅胶挤出机生产线_硅胶条挤出机_臣泽智能装备 贵州科比特-防雷公司厂家提供贵州防雷工程,防雷检测,防雷接地,防雷设备价格,防雷产品报价服务-贵州防雷检测公司 | 振动台-振动试验台-振动冲击台-广东剑乔试验设备有限公司 | 讲师宝经纪-专业培训机构师资供应商_培训机构找讲师、培训师、讲师经纪就上讲师宝经纪 |