MySQL事務(wù)

https://www.runoob.com/mysql/mysql-transaction.html

1.事務(wù)簡介

(1)在 MySQL 中只有使用了 Innodb 數(shù)據(jù)庫引擎的數(shù)據(jù)庫或表才支持事務(wù)。
(2)事務(wù)處理可以用來維護(hù)數(shù)據(jù)庫的完整性嗡贺,保證成批的 SQL 語句要么全部執(zhí)行机断,要么全部不執(zhí)行缭受。
(3)事務(wù)用來管理 insert,update,delete 語句艾帐。

2.事務(wù)四大特征

一般來說惰瓜,事務(wù)是必須滿足4個條件(ACID)::原子性(Atomicity梅桩,或稱不可分割性)塔鳍、一致性(Consistency)伯铣、隔離性(Isolation,又稱獨(dú)立性)轮纫、持久性(Durability)腔寡。

原子性:一個事務(wù)(transaction)中的所有操作,要么全部完成掌唾,要么全部不完成放前,不會結(jié)束在中間某個環(huán)節(jié)。事務(wù)在執(zhí)行過程中發(fā)生錯誤糯彬,會被回滾(Rollback)到事務(wù)開始前的狀態(tài)凭语,就像這個事務(wù)從來沒有執(zhí)行過一樣。

一致性:在事務(wù)開始之前和事務(wù)結(jié)束以后撩扒,數(shù)據(jù)庫的完整性沒有被破壞似扔。這表示寫入的資料必須完全符合所有的預(yù)設(shè)規(guī)則,這包含資料的精確度搓谆、串聯(lián)性以及后續(xù)數(shù)據(jù)庫可以自發(fā)性地完成預(yù)定的工作炒辉。(比如:A向B轉(zhuǎn)賬,不可能A扣了錢泉手,B卻沒有收到)

隔離性:數(shù)據(jù)庫允許多個并發(fā)事務(wù)同時對其數(shù)據(jù)進(jìn)行讀寫和修改的能力黔寇,隔離性可以防止多個事務(wù)并發(fā)執(zhí)行時由于交叉執(zhí)行而導(dǎo)致數(shù)據(jù)的不一致。事務(wù)隔離分為不同級別斩萌,包括讀未提交(Read uncommitted)缝裤、讀提交(read committed)、可重復(fù)讀(repeatable read)和串行化(Serializable)颊郎。(比u人:A正在從一張銀行卡里面取錢憋飞,在A取錢的過程中,B不能向這張銀行卡打錢)

持久性:事務(wù)處理結(jié)束后袭艺,對數(shù)據(jù)的修改就是永久的搀崭,即便系統(tǒng)故障也不會丟失叨粘。

3.事務(wù)提交猾编、回滾

mysql> start transaction;#手動開啟事務(wù)
mysql> insert into t_user(name) values('pp');
mysql> commit;#commit之后即可改變底層數(shù)據(jù)庫數(shù)據(jù)
mysql> select * from t_user;
+----+------+
| id | name |
+----+------+
|  1 | jay  |
|  2 | man  |
|  3 | pp   |
+----+------+
3 rows in set (0.00 sec)


mysql> start transaction;
mysql> insert into t_user(name) values('yy');
mysql> rollback;
mysql> select * from t_user;
+----+------+
| id | name |
+----+------+
|  1 | jay  |
|  2 | man  |
|  3 | pp   |
+----+------+
3 rows in set (0.00 sec)

4.事務(wù)特性--隔離性

4.1 隔離性有隔離級別(4個)

(1)讀未提交:read uncommitted
(2)讀已提交:read committed
(3)可重復(fù)讀:repeatable read
(4)串行化:serializable
數(shù)據(jù)庫事務(wù)隔離級別-- 臟讀瘤睹、幻讀、不可重復(fù)讀(清晰解釋)

臟讀 不可重復(fù)讀 幻讀
Read uncommitted
Read committed ×
Repeatable read × ×
Serializable × × ×

4.2 讀未提交

  • 事物A和事物B答倡,事物A未提交的數(shù)據(jù)轰传,事物B可以讀取到
  • 這里讀取到的數(shù)據(jù)叫做“臟數(shù)據(jù)”
  • 這種隔離級別最低,這種級別一般是在理論上存在瘪撇,數(shù)據(jù)庫隔離級別一般都高于該級別

公司發(fā)工資了获茬,領(lǐng)導(dǎo)把5000元打到singo的賬號上,但是該事務(wù)并未提交倔既,而singo正好去查看賬戶恕曲,發(fā)現(xiàn)工資已經(jīng)到賬,是5000元整渤涌,非常高 興佩谣。可是不幸的是实蓬,領(lǐng)導(dǎo)發(fā)現(xiàn)發(fā)給singo的工資金額不對茸俭,是2000元,于是迅速回滾了事務(wù)安皱,修改金額后调鬓,將事務(wù)提交,最后singo實(shí)際的工資只有 2000元酌伊,singo空歡喜一場腾窝。



出現(xiàn)上述情況,即我們所說的臟讀 居砖,兩個并發(fā)的事務(wù)燕锥,“事務(wù)A:領(lǐng)導(dǎo)給singo發(fā)工資”苟穆、“事務(wù)B:singo查詢工資賬戶”游两,事務(wù)B讀取了事務(wù)A尚未提交的數(shù)據(jù)。

4.3 讀已提交

  • 事物A和事物B葵孤,事物A提交的數(shù)據(jù)鼻由,事物B才能讀取到
  • 這種隔離級別高于讀未提交
  • 換句話說暇榴,對方事物提交之后的數(shù)據(jù),我當(dāng)前事物才能讀取到
  • 這種級別可以避免“臟數(shù)據(jù)”
  • 這種隔離級別會導(dǎo)致“不可重復(fù)讀取”
  • Oracle默認(rèn)隔離級別

singo拿著工資卡去消費(fèi)蕉世,系統(tǒng)讀取到卡里確實(shí)有2000元蔼紧,而此時她的老婆也正好在網(wǎng)上轉(zhuǎn)賬,把singo工資卡的2000元轉(zhuǎn)到另一賬戶狠轻,并在 singo之前提交了事務(wù)奸例,當(dāng)singo扣款時,系統(tǒng)檢查到singo的工資卡已經(jīng)沒有錢,扣款失敗查吊,singo十分納悶谐区,明明卡里有錢,為何......

出現(xiàn)上述情況逻卖,即我們所說的不可重復(fù)讀 宋列,兩個并發(fā)的事務(wù),“事務(wù)A:singo消費(fèi)”评也、“事務(wù)B:singo的老婆網(wǎng)上轉(zhuǎn)賬”炼杖,事務(wù)A事先讀取了數(shù)據(jù),事務(wù)B緊接了更新了數(shù)據(jù)盗迟,并提交了事務(wù)坤邪,而事務(wù)A再次讀取該數(shù)據(jù)時,數(shù)據(jù)已經(jīng)發(fā)生了改變罚缕。

當(dāng)隔離級別設(shè)置為Read committed 時罩扇,避免了臟讀,但是可能會造成不可重復(fù)讀怕磨。

大多數(shù)數(shù)據(jù)庫的默認(rèn)級別就是Read committed喂饥,比如Sql Server , Oracle。如何解決不可重復(fù)讀這一問題肠鲫,請看下一個隔離級別员帮。

4.4 可重復(fù)讀

  • 事務(wù)A和事務(wù)B,事務(wù)A提交之后的數(shù)據(jù)导饲,事務(wù)B讀取不到
  • 事務(wù)B是可重復(fù)讀取數(shù)據(jù)
  • 這種隔離級別高于讀已提交
  • 換句話說捞高,對方提交之后的數(shù)據(jù),我還是讀取不到
  • 這種隔離級別可以避免“不可重復(fù)讀取”渣锦,達(dá)到可重復(fù)讀取
  • 比如1點(diǎn)和2點(diǎn)讀到數(shù)據(jù)是同一個
  • MySQL默認(rèn)級別
  • 雖然可以達(dá)到可重復(fù)讀取硝岗,但是會導(dǎo)致“幻像讀”

當(dāng)隔離級別設(shè)置為Repeatable read 時,可以避免不可重復(fù)讀袋毙。當(dāng)singo拿著工資卡去消費(fèi)時型檀,一旦系統(tǒng)開始讀取工資卡信息(即事務(wù)開始),singo的老婆就不可能對該記錄進(jìn)行修改听盖,也就是singo的老婆不能在此時轉(zhuǎn)賬胀溺。

雖然Repeatable read避免了不可重復(fù)讀,但還有可能出現(xiàn)幻讀 皆看。

singo的老婆工作在銀行部門仓坞,她時常通過銀行內(nèi)部系統(tǒng)查看singo的信用卡消費(fèi)記錄。有一天腰吟,她正在查詢到singo當(dāng)月信用卡的總消費(fèi)金額 (select sum(amount) from transaction where month = 本月)為80元无埃,而singo此時正好在外面胡吃海塞后在收銀臺買單,消費(fèi)1000元,即新增了一條1000元的消費(fèi)記錄(insert transaction ... )嫉称,并提交了事務(wù)侦镇,隨后singo的老婆將singo當(dāng)月信用卡消費(fèi)的明細(xì)打印到A4紙上,卻發(fā)現(xiàn)消費(fèi)總額為1080元澎埠,singo的老婆很詫異,以為出現(xiàn)了幻覺始藕,幻讀就這樣產(chǎn)生了蒲稳。

4.5 串行化

  • 事務(wù)A和事務(wù)B,事務(wù)A在操作數(shù)據(jù)庫時伍派,事務(wù)B只能排隊(duì)等待
  • 這種隔離級別很少使用江耀,吞吐量太低,用戶體驗(yàn)差
  • 這種級別可以避免“幻像讀”诉植,每一次讀取的都是數(shù)據(jù)庫中真實(shí)存在數(shù)據(jù)祥国,事務(wù)A與事務(wù)B串行,而不并發(fā)

4.6 臟讀晾腔、幻讀舌稀、不可重復(fù)讀

1.臟讀:(讀取未提交數(shù)據(jù))

臟讀就是指當(dāng)一個事務(wù)正在訪問數(shù)據(jù),并且對數(shù)據(jù)進(jìn)行了修改灼擂,而這種修改還沒有提交到數(shù)據(jù)庫中壁查,這時,另外一個事務(wù)也訪問這個數(shù)據(jù)剔应,然后使用了這個數(shù)據(jù)睡腿。

時間順序 轉(zhuǎn)賬事務(wù) 取款事務(wù)
1 開始事務(wù)
2 開始事務(wù)
3 查詢賬戶余額為2000元
4 取款1000元,余額被更改為1000元(未提交)
5 查詢賬戶余額為1000元(產(chǎn)生臟數(shù)據(jù))
6 取款操作發(fā)生未知錯誤峻贮,事務(wù)回滾席怪,余額變更為2000元
7 轉(zhuǎn)入2000元,余額被更改為3000元(臟讀1000+2000)
8 提交事務(wù)
備注 按照正常邏輯此時賬戶應(yīng)該為4000元

2.不可重復(fù)讀:(前后多次讀取纤控,數(shù)據(jù)內(nèi)容不一致)

是指在一個事務(wù)內(nèi)挂捻,多次讀同一數(shù)據(jù)。在這個事務(wù)還沒有結(jié)束時船万,另外一個事務(wù)也訪問該同一數(shù)據(jù)细层。那么,在第一個事務(wù)中的兩次讀數(shù)據(jù)之間唬涧,由于第二個事務(wù)的修改疫赎,那么第一個事務(wù)兩次讀到的的數(shù)據(jù)可能是不一樣的。這樣就發(fā)生了在一個事務(wù)內(nèi)兩次讀到的數(shù)據(jù)是不一樣的碎节,因此稱為是不可重復(fù)讀捧搞。(即不能讀到相同的數(shù)據(jù)內(nèi)容)
例如,一個編輯人員兩次讀取同一文檔,但在兩次讀取之間胎撇,作者重寫了該文檔介粘。當(dāng)編輯人員第二次讀取文檔時,文檔已更改晚树。原始讀取不可重復(fù)姻采。如果只有在作者全部完成編寫后編輯人員才可以讀取文檔,則可以避免該問題爵憎。

時間順序 事務(wù)A 事務(wù)B
1 開始事務(wù)
2 第一次查詢慨亲,小明的年齡為20歲
3 開始事務(wù)
4 其他操作
5 更改小明的年齡為30歲
6 提交事務(wù)
7 第二次查詢,小明的年齡為30歲
備注 按照正確邏輯宝鼓,事務(wù)A前后兩次讀取到的數(shù)據(jù)應(yīng)該一致

3.幻讀:(前后多次讀取刑棵,數(shù)據(jù)總量不一致)

事務(wù)在插入已經(jīng)檢查過不存在的記錄時,驚奇的發(fā)現(xiàn)這些數(shù)據(jù)已經(jīng)存在了愚铡,之前的檢測獲取到的數(shù)據(jù)如同鬼影一般蛉签。

  • 例子1:
時間順序 事務(wù)A 事務(wù)B
1 開始事務(wù)
2 第一次查詢,數(shù)據(jù)總量為100條
3 開始事務(wù)
4 其他操作
5 新增100條數(shù)據(jù)
6 提交事務(wù)
7 第二次查詢沥寥,數(shù)據(jù)總量為200條
備注 按照正確邏輯碍舍,按照正確邏輯,事務(wù)A前后兩次讀取到的數(shù)據(jù)總量應(yīng)該一致
  • 例子2:
    在事務(wù)1中邑雅,查詢User表id為1的是用戶否存在乒验,如果不存在則插入一條id為1的數(shù)據(jù)。
select * from User where id = 1;

在事務(wù)1查詢結(jié)束后蒂阱,事務(wù)2往User表中插入了一條id為1的數(shù)據(jù)锻全。

insert into `User`(`id`, `name`) values (1, 'Joonwhee');

此時,由于事務(wù)1查詢到id為1的用戶不存在录煤,因此插入1條id為1的數(shù)據(jù)鳄厌。

insert into ` User`(`id`, `name`) values (1, 'Chillax');

但是由于事務(wù)2已經(jīng)插入了1條id為1的數(shù)據(jù),因此此時會報(bào)主鍵沖突妈踊,對于事務(wù)1 的業(yè)務(wù)來說是執(zhí)行失敗的了嚎,這里事務(wù)1 就是發(fā)生了幻讀,因?yàn)槭聞?wù)1讀取的數(shù)據(jù)狀態(tài)并不能支持他的下一步的業(yè)務(wù)廊营,見鬼了一樣歪泳。這里要靈活的理解讀取的意思,第一次select是讀取露筒,第二次的insert其實(shí)也屬于隱式的讀取呐伞,只不過是在mysql的機(jī)制中讀取的,插入數(shù)據(jù)也是要先讀取一下有沒有主鍵沖突才能決定是否執(zhí)行插入慎式。

  • 例子3:
    目前工資為1000的員工有10人伶氢。
    事務(wù)1趟径,讀取所有工資為1000的員工,共讀取10條記錄 癣防。
con1 = getConnection();  
Select * from employee where salary =1000;

這時另一個事務(wù)向employee表插入了一條員工記錄蜗巧,工資也為1000

con2 = getConnection();  
Insert into employee(employeeName,salary) values("Lili",1000);  
con2.commit();

事務(wù)1再次讀取所有工資為1000的員工,共讀取到了11條記錄蕾盯,這就產(chǎn)生了幻讀幕屹。

//con1  
select * from employee where salary =1000;

不可重復(fù)讀和幻讀到底有什么區(qū)別呢?

(1)不可重復(fù)讀是讀取了其他事務(wù)更改的數(shù)據(jù)级遭,針對update操作
解決:使用行級鎖望拖,鎖定該行,事務(wù)A多次讀取操作完成后才釋放該鎖装畅,這個時候才允許其他事務(wù)更改剛才的數(shù)據(jù)靠娱。

(2)幻讀是讀取了其他事務(wù)新增的數(shù)據(jù)沧烈,針對insert與delete操作
解決:使用表級鎖掠兄,鎖定整張表,事務(wù)A多次讀取數(shù)據(jù)總量之后才釋放該鎖锌雀,這個時候才允許其他事務(wù)新增數(shù)據(jù)蚂夕。

幻讀和不可重復(fù)讀都是指的一個事務(wù)范圍內(nèi)的操作受到其他事務(wù)的影響了。只不過幻讀是重點(diǎn)在插入和刪除腋逆,不可重復(fù)讀重點(diǎn)在修改

5婿牍、事務(wù)實(shí)現(xiàn)的原理

https://juejin.im/post/5cb2e3b46fb9a0686e40c5cb

下面我首先講實(shí)現(xiàn)事務(wù)功能的三個技術(shù),分別是日志文件(redo log 和 undo log)惩歉,鎖技術(shù)以及MVCC等脂,然后再講事務(wù)的實(shí)現(xiàn)原理,包括原子性是怎么實(shí)現(xiàn)的撑蚌,隔離型是怎么實(shí)現(xiàn)的等等上遥。最后在做一個總結(jié),希望大家能夠耐心看完

  • redo log與undo log介紹
  • mysql鎖技術(shù)以及MVCC基礎(chǔ)
  • 事務(wù)的實(shí)現(xiàn)原理

5.1 redo log 與 undo log介紹

5.1.1争涌、什么是redo log ?

redo log叫做重做日志粉楚,是用來實(shí)現(xiàn)事務(wù)的持久性。該日志文件由兩部分組成:重做日志緩沖(redo log buffer)以及重做日志文件(redo log),前者是在內(nèi)存中亮垫,后者在磁盤中模软。當(dāng)事務(wù)提交之后會把所有修改信息都會存到該日志中。


start transaction;
select balance from bank where name="zhangsan";
// 生成 重做日志 balance=600
update bank set balance = balance - 400; 
// 生成 重做日志 amount=400
update finance set amount = amount + 400;

5.1.2饮潦、redo log作用是什么燃异?

mysql 為了提升性能不會把每次的修改都實(shí)時同步到磁盤,而是會先存到Boffer Pool(緩沖池)里頭继蜡,把這個當(dāng)作緩存來用特铝。然后使用后臺線程去做緩沖池和磁盤之間的同步暑中。

那么問題來了,如果還沒來的同步的時候宕機(jī)或斷電了怎么辦鲫剿?還沒來得及執(zhí)行上面圖中紅色的操作鳄逾。這樣會導(dǎo)致丟部分已提交事務(wù)的修改信息!

所以引入了redo log來記錄已成功提交事務(wù)的修改信息灵莲,并且會把redo log持久化到磁盤雕凹,系統(tǒng)重啟之后在讀取redo log恢復(fù)最新數(shù)據(jù)。

  • 總結(jié):redo log是用來恢復(fù)數(shù)據(jù)的政冻,用于保障枚抵,已提交事務(wù)的持久化特性(記錄了已經(jīng)提交的操作)

5.1.3、什么是undo log明场?

undo log 叫做回滾日志汽摹,用于記錄數(shù)據(jù)被修改前的信息。他正好跟前面所說的重做日志所記錄的相反苦锨,重做日志記錄數(shù)據(jù)被修改后的信息逼泣。undo log主要記錄的是數(shù)據(jù)的邏輯變化,為了在發(fā)生錯誤時回滾之前的操作舟舒,需要將之前的操作都記錄下來拉庶,然后在發(fā)生錯誤時才可以回滾。
還用上面那兩張表



每次寫入數(shù)據(jù)或者修改數(shù)據(jù)之前都會把修改前的信息記錄到 undo log秃励。

5.1.4氏仗、undo log 有什么作用?

undo log 記錄事務(wù)修改之前版本的數(shù)據(jù)信息夺鲜,因此假如由于系統(tǒng)錯誤或者rollback操作而回滾的話可以根據(jù)undo log的信息來進(jìn)行回滾到?jīng)]被修改前的狀態(tài)皆尔。

  • 總結(jié):undo log是用來回滾數(shù)據(jù)的用于保障,未提交事務(wù)的原子性

5.2 mysql鎖技術(shù)以及MVCC基礎(chǔ)

5.2.1 mysql鎖技術(shù)

當(dāng)有多個請求來讀取表中的數(shù)據(jù)時可以不采取任何操作币励,但是多個請求里有讀請求慷蠕,又有修改請求時必須有一種措施來進(jìn)行并發(fā)控制。不然很有可能會造成不一致榄审。
讀寫鎖
解決上述問題很簡單砌们,只需用兩種鎖的組合來對讀寫請求進(jìn)行控制即可,這兩種鎖被稱為:

  • 共享鎖(shared lock),又叫做"讀鎖"
    讀鎖是可以共享的搁进,或者說多個讀請求可以共享一把鎖讀數(shù)據(jù)浪感,不會造成阻塞。

  • 排他鎖(exclusive lock),又叫做"寫鎖"
    寫鎖會排斥其他所有獲取鎖的請求饼问,一直阻塞影兽,直到寫入完成釋放鎖。


  • 總結(jié):通過讀寫鎖莱革,可以做到讀讀可以并行峻堰,但是不能做到寫讀讹开,寫寫并行

5.2.2 MVCC基礎(chǔ)

MVCC介紹
MVCC (MultiVersion Concurrency Control) 叫做多版本并發(fā)控制。一般情況下捐名,事務(wù)性儲存引擎不是只使用表鎖旦万,行加鎖的處理數(shù)據(jù),而是結(jié)合了MVCC機(jī)制镶蹋,以處理更多的并發(fā)問題成艘。Mvcc處理高并發(fā)能力最強(qiáng),但系統(tǒng)開銷 比最大(較表鎖贺归、行級鎖)淆两,這是最求高并發(fā)付出的代價(jià)。

InnoDB的 MVCC 拂酣,是通過在每行記錄的后面保存兩個隱藏的列來實(shí)現(xiàn)的秋冰。這兩個列, 一個保存了行的創(chuàng)建時間婶熬,一個保存了行的過期時間剑勾, 當(dāng)然存儲的并不是實(shí)際的時間值,而是系統(tǒng)版本號尸诽。

以上片段摘自《高性能Mysql》這本書對MVCC的定義甥材。他的主要實(shí)現(xiàn)思想是通過數(shù)據(jù)多版本來做到讀寫分離盯另。從而實(shí)現(xiàn)不加鎖讀進(jìn)而做到讀寫并行性含。MVCC在mysql中的實(shí)現(xiàn)依賴的是undo log與read view;

  • undo log :undo log 中記錄某行數(shù)據(jù)的多個版本的數(shù)據(jù)。
  • read view :用來判斷當(dāng)前版本數(shù)據(jù)的可見性



    MVCC的實(shí)現(xiàn)鸳惯,是通過保存數(shù)據(jù)在某個時間點(diǎn)的快照來實(shí)現(xiàn)的商蕴。也就是說,不管需要執(zhí)行多長時間芝发,每個事務(wù)看到的數(shù)據(jù)是一致的绪商。根據(jù)事務(wù)開始的時間不同,每個事務(wù)對同一張表辅鲸,同一時刻看到的數(shù)據(jù)可能是不一樣的格郁。不同存儲引擎的MVCC實(shí)現(xiàn)是不同的,典型的有樂觀(optimistic)并發(fā)控制和悲觀(pessimistic)并發(fā)控制独悴。

5.2.1 MVCC具體實(shí)現(xiàn)分析

輕松理解MYSQL MVCC 實(shí)現(xiàn)機(jī)制
下面,我們通過InnoDB的MVCC實(shí)現(xiàn)來分析MVCC使怎樣進(jìn)行并發(fā)控制的.
InnoDB的MVCC,是通過在每行記錄后面保存兩個隱藏的列來實(shí)現(xiàn)的,這兩個列例书,分別保存了這個行的創(chuàng)建時間,一個保存的是行的刪除時間刻炒。這里存儲的并不是實(shí)際的時間值,而是系統(tǒng)版本號(可以理解為事務(wù)的ID)决采,沒開始一個新的事務(wù),系統(tǒng)版本號就會自動遞增坟奥,事務(wù)開始時刻的系統(tǒng)版本號會作為事務(wù)的ID.下面看一下在REPEATABLE READ隔離級別下,MVCC具體是如何操作的.

  • 例子:
  • CREATE(創(chuàng)建表)
create table yang( 
id int primary key auto_increment, 
name varchar(20));
  • INSERT(插入數(shù)據(jù))
start transaction;
insert into yang values(NULL,'yang') ;
insert into yang values(NULL,'long');
insert into yang values(NULL,'fei');
commit;

假設(shè)系統(tǒng)的版本號從1開始.
對應(yīng)在數(shù)據(jù)中的表如下(后面兩列是隱藏列,我們通過查詢語句并看不到)

id name 創(chuàng)建時間(事務(wù)ID) 刪除時間(事務(wù)ID)
1 yang 1 undefined
2 long 1 undefined
3 fei 1 undefined
  • SELECT(查詢數(shù)據(jù))
    InnoDB會根據(jù)以下兩個條件檢查每行記錄:
    (1)InnoDB只會查找版本早于當(dāng)前事務(wù)版本的數(shù)據(jù)行(也就是,行的系統(tǒng)版本號小于或等于事務(wù)的系統(tǒng)版本號)树瞭,這樣可以確保事務(wù)讀取的行拇厢,要么是在事務(wù)開始前已經(jīng)存在的,要么是事務(wù)自身插入或者修改過的.
    (2)行的刪除版本要么未定義,要么大于當(dāng)前事務(wù)版本號,這可以確保事務(wù)讀取到的行晒喷,在事務(wù)開始之前未被刪除.
    只有a,b同時滿足的記錄孝偎,才能返回作為查詢結(jié)果.


  • DELETE(刪除數(shù)據(jù))
    InnoDB會為刪除的每一行保存當(dāng)前系統(tǒng)的版本號(事務(wù)的ID)作為刪除標(biāo)識.
    看下面的具體例子分析:
    第二個事務(wù),ID為2;
start transaction;
select * from yang;  //(1)
select * from yang;  //(2)
commit; 
假設(shè)1

假設(shè)在執(zhí)行這個事務(wù)ID為2的過程中,剛執(zhí)行到(1),這時,有另一個事務(wù)ID為3往這個表里插入了一條數(shù)據(jù); 第三個事務(wù)ID為3;

start transaction;
insert into yang values(NULL,'tian');
commit;

這時表中的數(shù)據(jù)如下:

id name 創(chuàng)建時間(事務(wù)ID) 刪除時間(事務(wù)ID)
1 yang 1 undefined
2 long 1 undefined
3 fei 1 undefined
4 tian 3 undefined

然后接著執(zhí)行事務(wù)2中的(2),由于id=4的數(shù)據(jù)的創(chuàng)建時間(事務(wù)ID為3),執(zhí)行當(dāng)前事務(wù)的ID為2,而InnoDB只會查找事務(wù)ID小于等于當(dāng)前事務(wù)ID的數(shù)據(jù)行,所以id=4的數(shù)據(jù)行并不會在執(zhí)行事務(wù)2中的(2)被檢索出來,在事務(wù)2中的兩條select 語句檢索出來的數(shù)據(jù)都只會下表:

id name 創(chuàng)建時間(事務(wù)ID) 刪除時間(事務(wù)ID)
1 yang 1 undefined
2 long 1 undefined
3 fei 1 undefined
假設(shè)2

假設(shè)在執(zhí)行這個事務(wù)ID為2的過程中,剛執(zhí)行到(1),假設(shè)事務(wù)執(zhí)行完事務(wù)3后,接著又執(zhí)行了事務(wù)4; 第四個事務(wù):

start   transaction;  
delete from yang where id=1;
commit;  

此時數(shù)據(jù)庫中的表如下:

id name 創(chuàng)建時間(事務(wù)ID) 刪除時間(事務(wù)ID)
1 yang 1 4
2 long 1 undefined
3 fei 1 undefined
4 tian 3 undefined

接著執(zhí)行事務(wù)ID為2的事務(wù)(2),根據(jù)SELECT 檢索條件可以知道,它會檢索創(chuàng)建時間(創(chuàng)建事務(wù)的ID)小于當(dāng)前事務(wù)ID的行和刪除時間(刪除事務(wù)的ID)大于當(dāng)前事務(wù)的行,而id=4的行上面已經(jīng)說過,而id=1的行由于刪除時間(刪除事務(wù)的ID)大于當(dāng)前事務(wù)的ID,所以事務(wù)2的(2)select * from yang也會把id=1的數(shù)據(jù)檢索出來.所以,事務(wù)2中的兩條select 語句檢索出來的數(shù)據(jù)都如下:

id name 創(chuàng)建時間(事務(wù)ID) 刪除時間(事務(wù)ID)
1 yang 1 4
2 long 1 undefined
3 fei 1 undefined


  • UPDATE
    InnoDB執(zhí)行UPDATE凉敲,實(shí)際上是新插入了一行記錄邪媳,并保存其創(chuàng)建時間為當(dāng)前事務(wù)的ID,同時保存當(dāng)前事務(wù)ID到要UPDATE的行的刪除時間.
假設(shè)3

假設(shè)在執(zhí)行完事務(wù)2的(1)后又執(zhí)行,其它用戶執(zhí)行了事務(wù)3,4,這時荡陷,又有一個用戶對這張表執(zhí)行了UPDATE操作;第5個事務(wù):

start  transaction;
update yang set name='Long' where id=2;
commit;

根據(jù)update的更新原則:會生成新的一行,并在原來要修改的列的刪除時間列上添加本事務(wù)ID,得到表如下:

id name 創(chuàng)建時間(事務(wù)ID) 刪除時間(事務(wù)ID)
1 yang 1 4
2 long 1 5
3 fei 1 undefined
4 tian 3 undefined
2 Long 5 undefined

繼續(xù)執(zhí)行事務(wù)2的(2),根據(jù)select 語句的檢索條件,得到下表:

id name 創(chuàng)建時間(事務(wù)ID) 刪除時間(事務(wù)ID)
1 yang 1 4
2 long 1 5
3 fei 1 undefined

還是和事務(wù)2中(1)select 得到相同的結(jié)果.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末雨效,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子废赞,更是在濱河造成了極大的恐慌徽龟,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件唉地,死亡現(xiàn)場離奇詭異据悔,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)耘沼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進(jìn)店門极颓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人群嗤,你說我怎么就攤上這事菠隆。” “怎么了狂秘?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵骇径,是天一觀的道長。 經(jīng)常有香客問我者春,道長破衔,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任钱烟,我火速辦了婚禮晰筛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拴袭。我一直安慰自己读第,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布稻扬。 她就那樣靜靜地躺著卦方,像睡著了一般。 火紅的嫁衣襯著肌膚如雪泰佳。 梳的紋絲不亂的頭發(fā)上盼砍,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天尘吗,我揣著相機(jī)與錄音,去河邊找鬼浇坐。 笑死睬捶,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的近刘。 我是一名探鬼主播擒贸,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼觉渴!你這毒婦竟也來了介劫?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤案淋,失蹤者是張志新(化名)和其女友劉穎座韵,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體踢京,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡誉碴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了瓣距。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片黔帕。...
    茶點(diǎn)故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蹈丸,靈堂內(nèi)的尸體忽然破棺而出成黄,到底是詐尸還是另有隱情,我是刑警寧澤白华,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布慨默,位于F島的核電站贩耐,受9級特大地震影響弧腥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜潮太,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一管搪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧铡买,春花似錦更鲁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至景埃,卻和暖如春媒至,著一層夾襖步出監(jiān)牢的瞬間顶别,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工拒啰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留驯绎,地道東北人。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓谋旦,卻偏偏與公主長得像剩失,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子册着,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評論 2 353

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

  • 什么是事務(wù)? 事務(wù)是邏輯上的一組操作拴孤,要么都執(zhí)行,要么都不執(zhí)行甲捏。 事務(wù)最經(jīng)典也經(jīng)常被拿出來說例子就是轉(zhuǎn)賬了乞巧。 假如...
    趙客縵胡纓v吳鉤霜雪明閱讀 2,668評論 2 82
  • 什么是事務(wù)? 事務(wù)是邏輯上的一組操作,要么都執(zhí)行摊鸡,要么都不執(zhí)行绽媒。 事務(wù)最經(jīng)典也經(jīng)常被拿出來說例子就是轉(zhuǎn)賬了。 假如...
    zwb_jianshu閱讀 333評論 0 0
  • http://baijiahao.baidu.com/s?id=1581064626251873652&wfr=s...
    hekang01閱讀 656評論 0 0
  • 一、(了解)定義 全稱(Transaction Control Language)翻譯成中文 事務(wù)控制語言,事務(wù)是...
    唯老閱讀 646評論 0 2
  • 今天一早媽媽回去了猎提。我心里也挺難受的获三。老師說,是因?yàn)榍榫w有情感在锨苏,所以我被情緒所帶動疙教,沒法理智去處理事情。因?yàn)樾奶?..
    黃玉翠閱讀 280評論 0 0