欧美阿v视频在线大全_亚洲欧美中文日韩V在线观看_www性欧美日韩欧美91_亚洲欧美日韩久久精品

主頁 > 知識庫 > MySQL事務的隔離性是如何實現的

MySQL事務的隔離性是如何實現的

熱門標簽:沈陽外呼系統有效果嗎 商家地圖標注圖片 四川穩定外呼系統公司 電話機器人接口是什么樣的 怎么在高德地圖標注多個點 百度地圖標注信息怎么修改 溫州語音外呼系統排名 福州外呼系統招商 AI智能云呼電話機器人怎么注冊

并發場景

最近做了一些分布式事務的項目,對事務的隔離性有了更深的認識,后續寫文章聊分布式事務。今天就復盤一下單機事務的隔離性是如何實現的?

隔離的本質就是控制并發,如果SQL語句就是串行執行的。那么數據庫的四大特性中就不會有隔離性這個概念了,也就不會有臟讀,不可重復讀,幻讀等各種問題了

對數據庫的各種并發操作,只有如下四種,寫寫,讀讀,讀寫和寫讀

寫-寫

事務A更新一條記錄的時候,事務B能同時更新同一條記錄嗎?

答案肯定是不能的,不然就會造成臟寫問題,那如何避免臟寫呢?答案就是加鎖

讀-讀

MySQL讀操作默認情況下不會加鎖,所以可以并行的讀

讀-寫 和 寫-讀

基于各種場景對并發操作容忍程度不同,MySQL就搞了個隔離性的概念。你自己根據業務場景選擇隔離級別。

√ 為會發生,×為不會發生

隔離級別 臟讀 不可重復讀 幻讀
read uncommitted(未提交讀)
read committed(提交讀) ×
repeatable read(可重復讀) × ×
serializable (可串行化) × × ×

所以你看,MySQL是通過鎖和隔離級別對MySQL進行并發控制的

MySQL中的鎖

行級鎖

InnoDB存儲引擎中有如下兩種類型的行級鎖

  • 共享鎖(Shared Lock,簡稱S鎖),在事務需要讀取一條記錄時,需要先獲取改記錄的S鎖
  • 排他鎖(Exclusive Lock,簡稱X鎖),在事務要改動一條記錄時,需要先獲取該記錄的X鎖

如果事務T1獲取了一條記錄的S鎖之后,事務T2也要訪問這條記錄。如果事務T2想再獲取這個記錄的S鎖,可以成功,這種情況稱為鎖兼容,如果事務T2想再獲取這個記錄的X鎖,那么此操作會被阻塞,直到事務T1提交之后將S鎖釋放掉

如果事務T1獲取了一條記錄的X鎖之后,那么不管事務T2接著想獲取該記錄的S鎖還是X鎖都會被阻塞,直到事務1提交,這種情況稱為鎖不兼容。

多個事務可以同時讀取記錄,即共享鎖之間不互斥,但共享鎖會阻塞排他鎖。排他鎖之間互斥

S鎖和X鎖之間的兼容關系如下

兼容性 X鎖 S鎖
X鎖 互斥 互斥
S鎖 互斥 兼容

update,delete,insert 都會自動給涉及到的數據加上排他鎖,select 語句默認不會加任何鎖

那什么情況下會對讀操作加鎖呢?

  • select … lock in share mode,對讀取的記錄加S鎖
  • select … for update ,對讀取的記錄加X鎖
  • 在事務中讀取記錄,對讀取的記錄加S鎖
  • 事務隔離級別在 SERIALIZABLE 下,對讀取的記錄加S鎖

InnoDB中有如下三種鎖

  • Record Lock:對單個記錄加鎖
  • Gap Lock:間隙鎖,鎖住記錄前面的間隙,不允許插入記錄
  • Next-key Lock:同時鎖住數據和數據前面的間隙,即數據和數據前面的間隙都不允許插入記錄

寫個Demo演示一下

CREATE TABLE `girl` (
  `id` int(11) NOT NULL,
  `name` varchar(255),
  `age` int(11),
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into girl values
(1, '西施', 20),
(5, '王昭君', 23),
(8, '貂蟬', 25),
(10, '楊玉環', 26),
(12, '陳圓圓', 20);

Record Lock

對單個記錄加鎖

如把id值為8的數據加一個Record Lock,示意圖如下


Record Lock也是有S鎖和X鎖之分的,兼容性和之前描述的一樣。

SQL執行加什么樣的鎖受很多條件的制約,比如事務的隔離級別,執行時使用的索引(如,聚集索引,非聚集索引等),因此就不詳細分析了,舉幾個簡單的例子。

-- READ UNCOMMITTED/READ COMMITTED/REPEATABLE READ 利用主鍵進行等值查詢
-- 對id=8的記錄加S型Record Lock
select * from girl where id = 8 lock in share mode;

-- READ UNCOMMITTED/READ COMMITTED/REPEATABLE READ 利用主鍵進行等值查詢
-- 對id=8的記錄加X型Record Lock
select * from girl where id = 8 for update;

Gap Lock

鎖住記錄前面的間隙,不允許插入記錄

MySQL在可重復讀隔離級別下可以通過MVCC和加鎖來解決幻讀問題

當前讀:加鎖
快照讀:MVCC

但是該如何加鎖呢?因為第一次執行讀取操作的時候,這些幻影記錄并不存在,我們沒有辦法加Record Lock,此時可以通過加Gap Lock解決,即對間隙加鎖。


如一個事務對id=8的記錄加間隙鎖,則意味著不允許別的事務在id=8的記錄前面的間隙插入新記錄,即id值在(5, 8)這個區間內的記錄是不允許立即插入的。直到加間隙鎖的事務提交后,id值在(5, 8)這個區間中的記錄才可以被提交

我們來看如下一個SQL的加鎖過程

-- REPEATABLE READ 利用主鍵進行等值查詢
-- 但是主鍵值并不存在
-- 對id=8的聚集索引記錄加Gap Lock
SELECT * FROM girl WHERE id = 7 LOCK IN SHARE MODE;

由于id=7的記錄不存在,為了禁止幻讀現象(避免在同一事務下執行相同的語句得到的結果集中有id=7的記錄),所以在當前事務提交前我們要預防別的事務插入id=7的記錄,此時在id=8的記錄上加一個Gap Lock即可,即不允許別的事務插入id值在(5, 8)這個區間的新記錄


給大家提一個問題,Gap Lock只能鎖定記錄前面的間隙,那么最后一條記錄后面的間隙該怎么鎖定?

其實mysql數據是存在頁中的,每個頁有2個偽記錄

  • Infimum記錄,表示該頁面中最小的記錄
  • upremum記錄,表示該頁面中最大的記錄

為了防止其它事務插入id值在(12, +∞)這個區間的記錄,我們可以給id=12記錄所在頁面的Supremum記錄加上一個gap鎖,此時就可以阻止其他事務插入id值在(12, +∞)這個區間的新記錄

Next-key Lock

同時鎖住數據和數據前面的間隙,即數據和數據前面的間隙都不允許插入記錄
所以你可以這樣理解Next-key Lock=Record Lock+Gap Lock

-- REPEATABLE READ 利用主鍵進行范圍查詢
-- 對id=8的聚集索引記錄加S型Record Lock
-- 對id>8的所有聚集索引記錄加S型Next-key Lock(包括Supremum偽記錄)
SELECT * FROM girl WHERE id >= 8 LOCK IN SHARE MODE;

因為要解決幻讀的問題,所以需要禁別的事務插入id>=8的記錄,所以

  • 對id=8的聚集索引記錄加S型Record Lock
  • 對id>8的所有聚集索引記錄加S型Next-key Lock(包括Supremum偽記錄)

表級鎖

表鎖也有S鎖和X鎖之分

在對某個表執行select,insert,update,delete語句時,innodb存儲引擎是不會為這個表添加表級別的S鎖或者X鎖。

在對表執行一些諸如ALTER TABLE,DROP TABLE這類的DDL語句時,會對這個表加X鎖,因此其他事務對這個表執行諸如SELECT INSERT UPDATE DELETE的語句會發生阻塞

在系統變量autocommit=0,innodb_table_locks = 1時,手動獲取InnoDB存儲引擎提供的表t的S鎖或者X鎖,可以這么寫

對表t加表級別的S鎖

lock tables t read

對表t加表級別的X鎖

lock tables t write

如果一個事務給表加了S鎖,那么

  • 別的事務可以繼續獲得該表的S鎖
  • 別的事務可以繼續獲得表中某些記錄的S鎖
  • 別的事務不可以繼續獲得該表的X鎖
  • 別的事務不可以繼續獲得表中某些記錄的X鎖

如果一個事務給表加了X鎖,那么

  • 別的事務不可以繼續獲得該表的S鎖
  • 別的事務不可以繼續獲得表中某些記錄的S鎖
  • 別的事務不可以繼續獲得該表的X鎖
  • 別的事務不可以繼續獲得表中某些記錄的X鎖

所以修改線上的表時一定要小心,因為會使大量事務阻塞,目前有很多成熟的修改線上表的方法,不再贅述

隔離級別

讀未提交:每次讀取最新的記錄,沒有做特殊處理
串行化:事務串行執行,不會產生并發

所以我們重點關注讀已提交可重復讀的隔離實現!

這兩種隔離級別是通過MVCC(多版本并發控制)來實現的,本質就是MySQL通過undolog存儲了多個版本的歷史數據,根據規則讀取某一歷史版本的數據,這樣就可以在無鎖的情況下實現讀寫并行,提高數據庫性能

那么undolog是如何存儲修改前的記錄?

對于使用InnoDB存儲引擎的表來說,聚集索引記錄中都包含下面2個必要的隱藏列

trx_id:一個事務每次對某條聚集索引記錄進行改動時,都會把該事務的事務id賦值給trx_id隱藏列

roll_pointer:每次對某條聚集索引記錄進行改動時,都會把舊的版本寫入undo日志中。這個隱藏列就相當于一個指針,通過他找到該記錄修改前的信息

如果一個記錄的name從貂蟬被依次改為王昭君,西施,會有如下的記錄,多個記錄構成了一個版本鏈

為了判斷版本鏈中哪個版本對當前事務是可見的,MySQL設計出了ReadView的概念。4個重要的內容如下

  • m_ids:在生成ReadView時,當前系統中活躍的事務id列表
  • min_trx_id:在生成ReadView時,當前系統中活躍的最小的事務id,也就是m_ids中的最小值
  • max_trx_id:在生成ReadView時,系統應該分配給下一個事務的事務id值
  • creator_trx_id:生成該ReadView的事務的事務id

當對表中的記錄進行改動時,執行insert,delete,update這些語句時,才會為事務分配唯一的事務id,否則一個事務的事務id值默認為0。

max_trx_id并不是m_ids中的最大值,事務id是遞增分配的。比如現在有事務id為1,2,3這三個事務,之后事務id為3的事務提交了,當有一個新的事務生成ReadView時,m_ids的值就包括1和2,min_trx_id的值就是1,max_trx_id的值就是4


執行過程如下:

  • 如果被訪問版本的trx_id=creator_id,意味著當前事務在訪問它自己修改過的記錄,所以該版本可以被當前事務訪問
  • 如果被訪問版本的trx_idmin_trx_id,表明生成該版本的事務在當前事務生成ReadView前已經提交,所以該版本可以被當前事務訪問
  • 被訪問版本的trx_id>=max_trx_id,表明生成該版本的事務在當前事務生成ReadView后才開啟,該版本不可以被當前事務訪問
  • 被訪問版本的trx_id是否在m_ids列表中
  • 4.1 是,創建ReadView時,該版本還是活躍的,該版本不可以被訪問。順著版本鏈找下一個版本的數據,繼續執行上面的步驟判斷可見性,如果最后一個版本還不可見,意味著記錄對當前事務完全不可見
  • 4.2 否,創建ReadView時,生成該版本的事務已經被提交,該版本可以被訪問

好了,我們知道了版本可見性的獲取規則,那么是怎么實現讀已提交和可重復讀的呢?

其實很簡單,就是生成ReadView的時機不同

舉個例子,先建立如下表

CREATE TABLE `girl` (
  `id` int(11) NOT NULL,
  `name` varchar(255),
  `age` int(11),
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Read Committed

Read Committed(讀已提交),每次讀取數據前都生成一個ReadView


下面是3個事務執行的過程,一行代表一個時間點

先分析一下5這個時間點select的執行過程

  • 系統中有兩個事務id分別為100,200的事務正在執行
  • 執行select語句時生成一個ReadView,mids=[100,200],min_trx_id=100,max_trx_id=201,creator_trx_id=0(select這個事務沒有執行更改操作,事務id默認為0)
  • 最新版本的name列為西施,該版本trx_id值為100,在mids列表中,不符合可見性要求,根據roll_pointer跳到下一個版本
  • 下一個版本的name列王昭君,該版本的trx_id值為100,也在mids列表內,因此也不符合要求,繼續跳到下一個版本
  • 下一個版本的name列為貂蟬,該版本的trx_id值為10,小于min_trx_id,因此最后返回的name值為貂蟬

再分析一下8這個時間點select的執行過程

  • 系統中有一個事務id為200的事務正在執行(事務id為100的事務已經提交)
  • 執行select語句時生成一個ReadView,mids=[200],min_trx_id=200,max_trx_id=201,creator_trx_id=0
  • 最新版本的name列為楊玉環,該版本trx_id值為200,在mids列表中,不符合可見性要求,根據roll_pointer跳到下一個版本
  • 下一個版本的name列為西施,該版本的trx_id值為100,小于min_trx_id,因此最后返回的name值為西施

當事務id為200的事務提交時,查詢得到的name列為楊玉環。

Repeatable Read

Repeatable Read(可重復讀),在第一次讀取數據時生成一個ReadView


可重復讀因為只在第一次讀取數據的時候生成ReadView,所以每次讀到的是相同的版本,即name值一直為貂蟬,具體的過程上面已經演示了兩遍了,我這里就不重復演示了,相信你一定會自己分析了。

參考博客

[1]https://souche.yuque.com/bggh1p/8961260/gyzlaf
[2]https://zhuanlan.zhihu.com/p/35477890

到此這篇關于MySQL事務的隔離性是如何實現的的文章就介紹到這了,更多相關MySQL事務的隔離性內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • Mysql隔離性之Read View的用法說明

標簽:西寧 汕尾 寶雞 七臺河 邯鄲 無錫 營口 來賓

巨人網絡通訊聲明:本文標題《MySQL事務的隔離性是如何實現的》,本文關鍵詞  MySQL,事務,的,隔,離性,是,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《MySQL事務的隔離性是如何實現的》相關的同類信息!
  • 本頁收集關于MySQL事務的隔離性是如何實現的的相關信息資訊供網民參考!
  • 推薦文章
    欧美阿v视频在线大全_亚洲欧美中文日韩V在线观看_www性欧美日韩欧美91_亚洲欧美日韩久久精品
  • <rt id="w000q"><acronym id="w000q"></acronym></rt>
  • <abbr id="w000q"></abbr>
    <rt id="w000q"></rt>
    国产十八熟妇av成人一区| 亚洲综合久久av一区二区三区| 亚洲欧美一区二区三区四区五区| 久久久久国产精品麻豆ai换脸 | 91免费版pro下载短视频| 蜜桃视频最新网址| 国产丝袜在线精品| 国产一区二区三区免费观看| 久久午夜福利电影| 久久这里只有精品视频网| 美腿丝袜亚洲三区| 国产交换配乱淫视频免费| 欧美日韩一区视频| 一级中文字幕一区二区| 下面一进一出好爽视频| 欧洲色大大久久| 一区二区三区不卡视频| 麻豆av免费看| 欧美精选一区二区| 日韩激情一区二区| 草草影院第一页| 精品88久久久久88久久久| 久草热8精品视频在线观看| 成熟人妻av无码专区| 国产校园另类小说区| 成人影视亚洲图片在线| 欧美日韩午夜视频| 亚洲天天做日日做天天谢日日欢| 91丨九色丨蝌蚪富婆spa| 欧美午夜精品一区二区三区| 亚洲成人久久影院| 无码人妻精品一区二区三应用大全| 精品久久人人做人人爰| 国产伦精品一区二区三区免费| 91麻豆免费视频网站| 亚洲美女在线一区| 91玉足脚交白嫩脚丫| 欧美tk—视频vk| 国产高清视频一区| 欧洲一区二区三区在线| 奇米亚洲午夜久久精品| www.黄色com| 一区二区三区日韩欧美精品| 精品人妻一区二区三区日产| 26uuu亚洲综合色欧美| 国产福利一区二区三区视频| 在线看一区二区| 日韩精品乱码免费| 亚洲欧美综合7777色婷婷| 亚洲天堂精品视频| 538国产视频| 国产美女免费无遮挡| 久久久精品免费免费| 99精品久久只有精品| 欧美夫妻性生活| 国产在线国偷精品产拍免费yy| 色哟哟国产精品免费观看| 亚州成人在线电影| 亚洲图片第一页| 亚洲综合网站在线观看| 精品国产成人亚洲午夜福利| 亚洲日本乱码在线观看| 免费看污片网站| 亚洲人成小说网站色在线| 日本丰满少妇裸体自慰 | 91av在线免费| 国产精品成人免费精品自在线观看| 中文字幕永久免费| 久久丝袜美腿综合| 深夜视频在线观看| 国产拍欧美日韩视频二区| 午夜诱惑痒痒网| 久久女同精品一区二区| 国产成人av免费观看| 久久九九久久九九| 污污免费在线观看| 国产精品久久久久久妇女6080| 麻豆国产精品一区| 一区二区三区中文字幕在线观看| 欧美丰满老妇熟乱xxxxyyy| 亚洲一区视频在线| 极品美妇后花庭翘臀娇吟小说| 午夜欧美在线一二页| 无码人妻精品一区二区三区夜夜嗨| 免费欧美在线视频| 在线精品视频一区二区三四| 国产一区二区三区高清播放| 91精品国产全国免费观看| 成人av网址在线| 久久亚洲影视婷婷| 欧美一级片黄色| 亚洲免费观看在线视频| 欧美色图17p| 免费的成人av| 欧美福利视频导航| 91麻豆.com| 成人免费在线视频| 国产毛片久久久久久久| 丝袜美腿亚洲色图| 欧美日韩在线三区| 91亚洲国产成人精品一区二三| 国产日韩精品一区| 蜜桃传媒一区二区亚洲| 日韩国产高清在线| 欧美绝品在线观看成人午夜影视| 成人激情小说乱人伦| 国产午夜精品一区二区| 扒开jk护士狂揉免费| 视频一区二区中文字幕| 欧美写真视频网站| 99久久亚洲一区二区三区青草 | 成人免费视频网站在线观看| 亚洲精品一区二区三区四区高清| 水蜜桃av无码| 亚洲444eee在线观看| 欧美三级资源在线| 91女神在线视频| 亚洲精品欧美在线| 色88888久久久久久影院野外| 成人av免费观看| 国产精品国模大尺度视频| 羞羞在线观看视频| 国产成人在线免费观看| 国产欧美日韩另类视频免费观看| 色屁屁草草影院ccyy.com| 久久av中文字幕片| 久久综合九色综合久久久精品综合| 精品黑人一区二区三区观看时间| 亚洲国产精品久久不卡毛片| 欧美日韩一区二区在线观看视频| 国产又黄又嫩又滑又白| 亚洲一卡二卡三卡四卡无卡久久 | 国产成人亚洲综合a∨猫咪| 国产视频一区不卡| 激情高潮到大叫狂喷水| 成人网在线播放| 亚洲欧美日韩国产综合| 欧美性受极品xxxx喷水| 波多野结衣三级视频| 亚洲国产精品一区二区www在线 | 亚洲高潮女人毛茸茸| 国产一区二区三区免费在线观看| 欧美国产综合一区二区| a在线视频播放观看免费观看| 不卡影院免费观看| 一区二区三区久久久| 欧美日韩一区三区四区| 亚洲综合自拍网| 毛片一区二区三区| 久久久久99精品一区| 永久免费看片视频教学| 97久久超碰精品国产| 亚洲成人久久影院| 精品国产91久久久久久久妲己| 潮喷失禁大喷水aⅴ无码| 成人黄页毛片网站| 亚洲二区视频在线| 精品电影一区二区| 91麻豆免费视频网站| 亚洲精品鲁一鲁一区二区三区| 麻豆一区二区三| 国产精品欧美久久久久无广告| 在线免费观看日本欧美| 三级电影在线看| 国产麻豆一精品一av一免费| 亚洲天堂精品在线观看| 欧美一级欧美三级在线观看 | 国产精品嫩草影院av蜜臀| 在线视频欧美精品| 精品无码在线视频| 国产.精品.日韩.另类.中文.在线.播放| 亚洲女性喷水在线观看一区| 欧美一区二区黄| 一级免费黄色录像| 美女流白浆视频| 久久99国产精品久久99 | √…a在线天堂一区| 欧美精品日日鲁夜夜添| 波多野在线播放| 95精品视频在线| 麻豆一区二区99久久久久| 国产精品免费看片| 欧美精品777| 在线观看亚洲大片短视频| 亚洲欧美一区二区三区极速播放| 91官网在线免费观看| 熟女少妇一区二区三区| 成人av影视在线观看| 日本在线不卡一区| 最新中文字幕av| 日韩精品xxx| 国产一区91精品张津瑜| 亚洲国产精品久久久男人的天堂 | 一区2区3区在线看| 国产婷婷一区二区| 91精品国产免费| 日本韩国一区二区三区视频| 91资源在线播放| 亚州av综合色区无码一区| eeuss影院一区二区三区|