【Mysql篇】【MySql事務(wù)及ACID實(shí)現(xiàn)的原理】

二線碼農(nóng)的糧食絮重,原文地址

1.邏輯架構(gòu)和存儲(chǔ)引擎

簡(jiǎn)單了解一下Mysql主要組成部分。


image.png

2.Mysql默認(rèn)事務(wù)開啟方式

MySQL 中默認(rèn)采用的是自動(dòng)提交(autocommit)模式鸣剪,如下所示:


image.png

在自動(dòng)提交模式下蝉衣,如果沒(méi)有 start transaction 顯式地開始一個(gè)事務(wù)肪凛,那么每個(gè) sql 語(yǔ)句都會(huì)被當(dāng)做一個(gè)事務(wù)執(zhí)行提交操作劳景。
通過(guò)如下方式配紫,可以關(guān)閉 autocommit;需要注意的是,autocommit 參數(shù)是針對(duì)連接的审孽,在一個(gè)連接中修改了參數(shù)县袱,不會(huì)對(duì)其他連接產(chǎn)生影響。


image

如果關(guān)閉了 autocommit佑力,則所有的 sql 語(yǔ)句都在一個(gè)事務(wù)中式散,直到執(zhí)行了 commit 或 rollback,該事務(wù)結(jié)束打颤,同時(shí)開始了另外一
個(gè)事務(wù)暴拄。
特殊操作

在 MySQL 中,存在一些特殊的命令编饺,如果在事務(wù)中執(zhí)行了這些命令乖篷,會(huì)馬上強(qiáng)制執(zhí)行 commit 提交事務(wù);如 DDL 語(yǔ)句(create table/drop table/alter/table)、lock tables 語(yǔ)句等等透且。
不過(guò)那伐,常用的 select、insert石蔗、update 和 delete 命令罕邀,都不會(huì)強(qiáng)制提交事務(wù)。

3.ACID特性

ACID 是衡量事務(wù)的四個(gè)特性:
原子性(Atomicity养距,或稱不可分割性)一致性(Consistency)隔離性(Isolation)持久性(Durability)按照嚴(yán)格的標(biāo)準(zhǔn)诉探,只有同時(shí)滿足 ACID 特性才是事務(wù);但是在各大數(shù)據(jù)庫(kù)廠商的實(shí)現(xiàn)中,真正滿足 ACID 的事務(wù)少之又少棍厌。
例如 MySQL 的 NDB Cluster 事務(wù)不滿足持久性和隔離性;InnoDB 默認(rèn)事務(wù)隔離級(jí)別是可重復(fù)讀肾胯,不滿足隔離性;Oracle 默認(rèn)的事務(wù)隔離級(jí)別為 READ COMMITTED,不滿足隔離性……
因此與其說(shuō) ACID 是事務(wù)必須滿足的條件耘纱,不如說(shuō)它們是衡量事務(wù)的四個(gè)維度敬肚。

下面將詳細(xì)介紹 ACID 特性及其實(shí)現(xiàn)原理,為了便于理解束析,介紹的順序不是嚴(yán)格按照 A-C-I-D艳馒。
ACID 特性及其實(shí)現(xiàn)原理

原子性

原子性是指一個(gè)事務(wù)是一個(gè)不可分割的工作單位,其中的操作要么都做员寇,要么都不做弄慰。
如果事務(wù)中一個(gè) sql 語(yǔ)句執(zhí)行失敗,則已執(zhí)行的語(yǔ)句也必須回滾蝶锋,數(shù)據(jù)庫(kù)退回到事務(wù)前的狀態(tài)陆爽。

實(shí)現(xiàn)原理:undo log
在說(shuō)明原子性原理之前,首先介紹一下 MySQL 的事務(wù)日志扳缕。MySQL 的日志有很多種慌闭,如二進(jìn)制日志别威、錯(cuò)誤日志、查詢?nèi)罩韭刻蕖⒙樵內(nèi)罩镜取?br> 此外
InnoDB 存儲(chǔ)引擎還提供了兩種事務(wù)日志:
redo log(重做日志)undo log(回滾日志)其中 redo log 用于保證事務(wù)持久性;undo log 則是事務(wù)原子性和隔離性實(shí)現(xiàn)的基礎(chǔ)省古。

下面說(shuō)回 undo log。實(shí)現(xiàn)原子性的關(guān)鍵仔拟,是當(dāng)事務(wù)回滾時(shí)能夠撤銷所有已經(jīng)成功執(zhí)行的 sql 語(yǔ)句衫樊。
InnoDB 實(shí)現(xiàn)回滾飒赃,靠的是 undo log:

當(dāng)事務(wù)對(duì)數(shù)據(jù)庫(kù)進(jìn)行修改時(shí)利花,InnoDB 會(huì)生成對(duì)應(yīng)的 undo log。如果事務(wù)執(zhí)行失敗或調(diào)用了 rollback载佳,導(dǎo)致事務(wù)需要回滾炒事,便可以利用 undo log 中的信息將數(shù)據(jù)回滾到修改之前的樣子。undo log 屬于邏輯日志蔫慧,它記錄的是 sql 執(zhí)行相關(guān)的信息挠乳。當(dāng)發(fā)生回滾時(shí),InnoDB 會(huì)根據(jù) undo log 的內(nèi)容做與之前相反的工作:

對(duì)于每個(gè) insert姑躲,回滾時(shí)會(huì)執(zhí)行 delete睡扬。對(duì)于每個(gè) delete,回滾時(shí)會(huì)執(zhí)行 insert黍析。對(duì)于每個(gè) update卖怜,回滾時(shí)會(huì)執(zhí)行一個(gè)相反的 update,把數(shù)據(jù)改回去阐枣。以 update 操作為例:當(dāng)事務(wù)執(zhí)行 update 時(shí)马靠,其生成的 undo log 中會(huì)包含被修改行的主鍵(以便知道修改了哪些行)、修改了哪些列蔼两、這些列在修改前后的值等信息甩鳄,回滾時(shí)便可以使用這些信息將數(shù)據(jù)還原到 update 之前的狀態(tài)。

持久性

持久性是指事務(wù)一旦提交额划,它對(duì)數(shù)據(jù)庫(kù)的改變就應(yīng)該是永久性的妙啃。接下來(lái)的其他操作或故障不應(yīng)該對(duì)其有任何影響。

實(shí)現(xiàn)原理:redo log
redo log 和 undo log 都屬于 InnoDB 的事務(wù)日志俊戳。下面先聊一下 redo log 存在的背景彬祖。

InnoDB 作為 MySQL 的存儲(chǔ)引擎,數(shù)據(jù)是存放在磁盤中的品抽,但如果每次讀寫數(shù)據(jù)都需要磁盤 IO储笑,效率會(huì)很低。

為此圆恤,InnoDB 提供了緩存(Buffer Pool)突倍,Buffer Pool 中包含了磁盤中部分?jǐn)?shù)據(jù)頁(yè)的映射腔稀,作為訪問(wèn)數(shù)據(jù)庫(kù)的緩沖:

當(dāng)從數(shù)據(jù)庫(kù)讀取數(shù)據(jù)時(shí),會(huì)首先從 Buffer Pool 中讀取羽历,如果 Buffer Pool 中沒(méi)有焊虏,則從磁盤讀取后放入 Buffer Pool。當(dāng)向數(shù)據(jù)庫(kù)寫入數(shù)據(jù)時(shí)秕磷,會(huì)首先寫入 Buffer Pool诵闭,Buffer Pool 中修改的數(shù)據(jù)會(huì)定期刷新到磁盤中(這一過(guò)程稱為刷臟)。Buffer Pool 的使用大大提高了讀寫數(shù)據(jù)的效率澎嚣,但是也帶來(lái)了新的問(wèn)題:如果 MySQL 宕機(jī)疏尿,而此時(shí) Buffer Pool 中修改的數(shù)據(jù)還沒(méi)有刷新到磁盤,就會(huì)導(dǎo)致數(shù)據(jù)的丟失易桃,事務(wù)的持久性無(wú)法保證褥琐。

于是,redo log 被引入來(lái)解決這個(gè)問(wèn)題:當(dāng)數(shù)據(jù)修改時(shí)晤郑,除了修改 Buffer Pool 中的數(shù)據(jù)敌呈,還會(huì)在 redo log 記錄這次操作;當(dāng)事務(wù)提交時(shí),會(huì)調(diào)用 fsync 接口對(duì) redo log 進(jìn)行刷盤造寝。

如果 MySQL 宕機(jī)磕洪,重啟時(shí)可以讀取 redo log 中的數(shù)據(jù),對(duì)數(shù)據(jù)庫(kù)進(jìn)行恢復(fù)诫龙。

redo log 采用的是 WAL(Write-ahead logging析显,預(yù)寫式日志),所有修改先寫入日志赐稽,再更新到 Buffer Pool叫榕,保證了數(shù)據(jù)不會(huì)因 MySQL 宕機(jī)而丟失,從而滿足了持久性要求姊舵。

既然 redo log 也需要在事務(wù)提交時(shí)將日志寫入磁盤晰绎,為什么它比直接將 Buffer Pool 中修改的數(shù)據(jù)寫入磁盤(即刷臟)要快呢?

主要有以下兩方面的原因:

刷臟是隨機(jī) IO,因?yàn)槊看涡薷牡臄?shù)據(jù)位置隨機(jī)括丁,但寫 redo log 是追加操作荞下,屬于順序 IO。刷臟是以數(shù)據(jù)頁(yè)(Page)為單位的史飞,MySQL 默認(rèn)頁(yè)大小是 16KB尖昏,一個(gè) Page 上一個(gè)小修改都要整頁(yè)寫入;而 redo log 中只包含真正需要寫入的部分,無(wú)效 IO 大大減少构资。redo log 與 binlog

我們知道抽诉,在 MySQL 中還存在 binlog(二進(jìn)制日志)也可以記錄寫操作并用于數(shù)據(jù)的恢復(fù),但二者是有著根本的不同的吐绵。

作用不同:

redo log 是用于 crash recovery 的迹淌,保證 MySQL 宕機(jī)也不會(huì)影響持久性;binlog 是用于 point-in-time recovery 的河绽,保證服務(wù)器可以基于時(shí)間點(diǎn)恢復(fù)數(shù)據(jù),此外 binlog 還用于主從復(fù)制唉窃。層次不同:

redo log 是 InnoDB 存儲(chǔ)引擎實(shí)現(xiàn)的耙饰,而 binlog 是 MySQL 的服務(wù)器層(可以參考文章前面對(duì) MySQL 邏輯架構(gòu)的介紹)實(shí)現(xiàn)的,同時(shí)支持 InnoDB 和其他存儲(chǔ)引擎纹份。內(nèi)容不同:

redo log 是物理日志苟跪,內(nèi)容基于磁盤的 Page。binlog 是邏輯日志蔓涧,內(nèi)容是一條條 sql件已。寫入時(shí)機(jī)不同:

redo log 的寫入時(shí)機(jī)相對(duì)多元。前面曾提到蠢笋,當(dāng)事務(wù)提交時(shí)會(huì)調(diào)用 fsync 對(duì) redo log 進(jìn)行刷盤;這是默認(rèn)情況下的策略拨齐,修改 innodb_flush_log_at_trx_commit 參數(shù)可以改變?cè)摬呗粤墼桑聞?wù)的持久性將無(wú)法保證昨寞。除了事務(wù)提交時(shí),還有其他刷盤時(shí)機(jī):如 master thread 每秒刷盤一次 redo log 等厦滤,這樣的好處是不一定要等到 commit 時(shí)刷盤援岩,commit 速度大大加快。

binlog 在事務(wù)提交時(shí)寫入掏导。

隔離性

與原子性享怀、持久性側(cè)重于研究事務(wù)本身不同,隔離性研究的是不同事務(wù)之間的相互影響趟咆。
隔離性是指事務(wù)內(nèi)部的操作與其他事務(wù)是隔離的添瓷,并發(fā)執(zhí)行的各個(gè)事務(wù)之間不能互相干擾。

嚴(yán)格的隔離性值纱,對(duì)應(yīng)了事務(wù)隔離級(jí)別中的 Serializable(可串行化)鳞贷,但實(shí)際應(yīng)用中出于性能方面的考慮很少會(huì)使用可串行化。

隔離性追求的是并發(fā)情形下事務(wù)之間互不干擾虐唠。簡(jiǎn)單起見(jiàn)搀愧,我們僅考慮最簡(jiǎn)單的讀操作和寫操作(暫時(shí)不考慮帶鎖讀等特殊操作)。
那么隔離性的探討疆偿,主要可以分為兩個(gè)方面:

(一個(gè)事務(wù))寫操作對(duì)(另一個(gè)事務(wù))寫操作的影響:鎖機(jī)制保證隔離性咱筛。(一個(gè)事務(wù))寫操作對(duì)(另一個(gè)事務(wù))讀操作的影響:MVCC 保證隔離性。鎖機(jī)制
首先來(lái)看兩個(gè)事務(wù)的寫操作之間的相互影響杆故。隔離性要求同一時(shí)刻只能有一個(gè)事務(wù)對(duì)數(shù)據(jù)進(jìn)行寫操作迅箩,InnoDB 通過(guò)鎖機(jī)制來(lái)保證這一點(diǎn)。
鎖機(jī)制的基本原理可以概括為:

事務(wù)在修改數(shù)據(jù)之前处铛,需要先獲得相應(yīng)的鎖饲趋。獲得鎖之后叉钥,事務(wù)便可以修改數(shù)據(jù)。該事務(wù)操作期間篙贸,這部分?jǐn)?shù)據(jù)是鎖定的投队,其他事務(wù)如果需要修改數(shù)據(jù),需要等待當(dāng)前事務(wù)提交或回滾后釋放鎖爵川。行鎖與表鎖:按照粒度敷鸦,鎖可以分為表鎖、行鎖以及其他位于二者之間的鎖寝贡。

表鎖在操作數(shù)據(jù)時(shí)會(huì)鎖定整張表扒披,并發(fā)性能較差;行鎖則只鎖定需要操作的數(shù)據(jù),并發(fā)性能好圃泡。

但是由于加鎖本身需要消耗資源(獲得鎖碟案、檢查鎖、釋放鎖等都需要消耗資源)颇蜡,因此在鎖定數(shù)據(jù)較多情況下使用表鎖可以節(jié)省大量資源价说。

MySQL 中不同的存儲(chǔ)引擎支持的鎖是不一樣的,例如 MyIsam 只支持表鎖风秤,而 InnoDB 同時(shí)支持表鎖和行鎖鳖目,且出于性能考慮,絕大多數(shù)情況下使用的都是行鎖缤弦。

如何查看鎖信息?有多種方法可以查看 InnoDB 中鎖的情況领迈,例如:

select * from information_schema.innodb_locks;

鎖的概況show engine innodb status; #InnoDB整體狀態(tài),其中包括鎖的情況下面來(lái)看一個(gè)例子:

在事務(wù)A中執(zhí)行:start transaction;update account SET balance = 1000 where id = 1;
在事務(wù)B中執(zhí)行:start transaction;update account SET balance = 2000 where id = 1;

此時(shí)查看鎖的情況:


image

show engine innodb status 查看鎖相關(guān)的部分:

image

通過(guò)上述命令可以查看事務(wù) 24052 和 24053 占用鎖的情況;其中 lock_type 為 RECORD碍沐,代表鎖為行鎖(記錄鎖);lock_mode 為 X狸捅,代表排它鎖(寫鎖)。

除了排它鎖(寫鎖)之外累提,MySQL 中還有共享鎖(讀鎖)的概念尘喝。由于本文重點(diǎn)是 MySQL 事務(wù)的實(shí)現(xiàn)原理,因此對(duì)鎖的介紹到此為止刻恭。

事務(wù)存在的隔離級(jí)別

介紹完寫操作之間的相互影響瞧省,下面討論寫操作對(duì)讀操作的影響。
臟讀鳍贾、不可重復(fù)讀和幻讀

①臟讀:當(dāng)前事務(wù)(A)中可以讀到其他事務(wù)(B)未提交的數(shù)據(jù)(臟數(shù)據(jù))鞍匾,這種現(xiàn)象是臟讀。

舉例如下(以賬戶余額表為例):

image

②不可重復(fù)讀:在事務(wù) A 中先后兩次讀取同一個(gè)數(shù)據(jù)骑科,兩次讀取的結(jié)果不一樣橡淑,這種現(xiàn)象稱為不可重復(fù)讀。

臟讀與不可重復(fù)讀的區(qū)別在于:前者讀到的是其他事務(wù)未提交的數(shù)據(jù)咆爽,后者讀到的是其他事務(wù)已提交的數(shù)據(jù)梁棠。

舉例如下:

image

③幻讀:在事務(wù) A 中按照某個(gè)條件先后兩次查詢數(shù)據(jù)庫(kù)置森,兩次查詢結(jié)果的條數(shù)不同,這種現(xiàn)象稱為幻讀符糊。

不可重復(fù)讀與幻讀的區(qū)別可以通俗的理解為:前者是數(shù)據(jù)變了凫海,后者是數(shù)據(jù)的行數(shù)變了。

舉例如下:

image

事務(wù)隔離級(jí)別

sql 標(biāo)準(zhǔn)中定義了四種隔離級(jí)別男娄,并規(guī)定了每種隔離級(jí)別下上述幾個(gè)問(wèn)題是否存在行贪。

一般來(lái)說(shuō),隔離級(jí)別越低模闲,系統(tǒng)開銷越低建瘫,可支持的并發(fā)越高,但隔離性也越差尸折。

隔離級(jí)別與讀問(wèn)題的關(guān)系如下:

image

在實(shí)際應(yīng)用中啰脚,讀未提交在并發(fā)時(shí)會(huì)導(dǎo)致很多問(wèn)題,而性能相對(duì)于其他隔離級(jí)別提高卻很有限实夹,因此使用較少橄浓。

可串行化強(qiáng)制事務(wù)串行,并發(fā)效率很低收擦,只有當(dāng)對(duì)數(shù)據(jù)一致性要求極高且可以接受沒(méi)有并發(fā)時(shí)使用贮配,因此使用也較少谍倦。

因此在大多數(shù)數(shù)據(jù)庫(kù)系統(tǒng)中塞赂,默認(rèn)的隔離級(jí)別是讀已提交(如 Oracle)或可重復(fù)讀(后文簡(jiǎn)稱 RR)。

可以通過(guò)如下兩個(gè)命令分別查看全局隔離級(jí)別和本次會(huì)話的隔離級(jí)別:

image
image

InnoDB 默認(rèn)的隔離級(jí)別是 RR昼蛀,后文會(huì)重點(diǎn)介紹 RR宴猾。需要注意的是,在 SQL 標(biāo)準(zhǔn)中叼旋,RR 是無(wú)法避免幻讀問(wèn)題的仇哆,但是 InnoDB 實(shí)現(xiàn)的 RR 避免了幻讀問(wèn)題。

MVCC

RR 解決臟讀夫植、不可重復(fù)讀讹剔、幻讀等問(wèn)題,使用的是 MVCC:MVCC 全稱 Multi-Version Concurrency Control详民,即多版本的并發(fā)控制協(xié)議延欠。

下面的例子很好的體現(xiàn)了 MVCC 的特點(diǎn):在同一時(shí)刻,不同的事務(wù)讀取到的數(shù)據(jù)可能是不同的(即多版本)——在 T5 時(shí)刻沈跨,事務(wù) A 和事務(wù) C 可以讀取到不同版本的數(shù)據(jù)由捎。

image

MVCC 最大的優(yōu)點(diǎn)是讀不加鎖,因此讀寫不沖突饿凛,并發(fā)性能好狞玛。InnoDB 實(shí)現(xiàn) MVCC软驰,多個(gè)版本的數(shù)據(jù)可以共存稠集,主要是依靠數(shù)據(jù)的隱藏列(也可以稱之為標(biāo)記位)和 undo log郊丛。

其中數(shù)據(jù)的隱藏列包括了該行數(shù)據(jù)的版本號(hào)答朋、刪除時(shí)間几苍、指向 undo log 的指針等等线定。

當(dāng)讀取數(shù)據(jù)時(shí)受楼,MySQL 可以通過(guò)隱藏列判斷是否需要回滾并找到回滾需要的 undo log酒繁,從而實(shí)現(xiàn) MVCC;隱藏列的詳細(xì)格式不再展開孽惰。

下面結(jié)合前文提到的幾個(gè)問(wèn)題分別說(shuō)明膳凝。

①臟讀

image

當(dāng)事務(wù) A 在 T3 時(shí)間節(jié)點(diǎn)讀取 zhangsan 的余額時(shí)碑隆,會(huì)發(fā)現(xiàn)數(shù)據(jù)已被其他事務(wù)修改,且狀態(tài)為未提交蹬音。

此時(shí)事務(wù) A 讀取最新數(shù)據(jù)后上煤,根據(jù)數(shù)據(jù)的 undo log 執(zhí)行回滾操作,得到事務(wù) B 修改前的數(shù)據(jù)著淆,從而避免了臟讀劫狠。

②不可重復(fù)讀

image.png

當(dāng)事務(wù) A 在 T2 節(jié)點(diǎn)第一次讀取數(shù)據(jù)時(shí),會(huì)記錄該數(shù)據(jù)的版本號(hào)(數(shù)據(jù)的版本號(hào)是以 row 為單位記錄的)永部,假設(shè)版本號(hào)為 1;當(dāng)事務(wù) B 提交時(shí)独泞,該行記錄的版本號(hào)增加,假設(shè)版本號(hào)為 2苔埋。

當(dāng)事務(wù) A 在 T5 再一次讀取數(shù)據(jù)時(shí)懦砂,發(fā)現(xiàn)數(shù)據(jù)的版本號(hào)(2)大于第一次讀取時(shí)記錄的版本號(hào)(1),因此會(huì)根據(jù) undo log 執(zhí)行回滾操作组橄,得到版本號(hào)為 1 時(shí)的數(shù)據(jù)荞膘,從而實(shí)現(xiàn)了可重復(fù)讀。

③幻讀

InnoDB 實(shí)現(xiàn)的 RR 通過(guò) next-keylock 機(jī)制避免了幻讀現(xiàn)象玉工。

next-keylock 是行鎖的一種羽资,實(shí)現(xiàn)相當(dāng)于 record lock(記錄鎖) + gap lock(間隙鎖);其特點(diǎn)是不僅會(huì)鎖住記錄本身(record lock 的功能),還會(huì)鎖定一個(gè)范圍(gap lock 的功能)遵班。

當(dāng)然屠升,這里我們討論的是不加鎖讀:此時(shí)的 next-key lock 并不是真的加鎖,只是為讀取的數(shù)據(jù)增加了標(biāo)記(標(biāo)記內(nèi)容包括數(shù)據(jù)的版本號(hào)等);準(zhǔn)確起見(jiàn)姑且稱之為類 next-key lock 機(jī)制狭郑。

還是以前面的例子來(lái)說(shuō)明:

image

當(dāng)事務(wù) A 在 T2 節(jié)點(diǎn)第一次讀取 0

這樣當(dāng) T5 時(shí)刻再次讀取 0

小結(jié):概括來(lái)說(shuō)腹暖,InnoDB 實(shí)現(xiàn)的 RR,通過(guò)鎖機(jī)制愿阐、數(shù)據(jù)的隱藏列微服、undo log 和類 next-key lock,實(shí)現(xiàn)了一定程度的隔離性,可以滿足大多數(shù)場(chǎng)景的需要以蕴。

不過(guò)需要說(shuō)明的是糙麦,RR 雖然避免了幻讀問(wèn)題,但是畢竟不是 Serializable丛肮,不能保證完全的隔離赡磅。

下面是一個(gè)例子,大家可以自己驗(yàn)證一下:

image

一致性

一致性是指事務(wù)執(zhí)行結(jié)束后宝与,數(shù)據(jù)庫(kù)的完整性約束沒(méi)有被破壞焚廊,事務(wù)執(zhí)行的前后都是合法的數(shù)據(jù)狀態(tài)。

數(shù)據(jù)庫(kù)的完整性約束包括但不限于:

實(shí)體完整性(如行的主鍵存在且唯一)列完整性(如字段的類型习劫、大小咆瘟、長(zhǎng)度要符合要求)外鍵約束用戶自定義完整性(如轉(zhuǎn)賬前后,兩個(gè)賬戶余額的和應(yīng)該不變)實(shí)現(xiàn)

可以說(shuō)诽里,一致性是事務(wù)追求的最終目標(biāo):前面提到的原子性袒餐、持久性和隔離性,都是為了保證數(shù)據(jù)庫(kù)狀態(tài)的一致性谤狡。此外灸眼,除了數(shù)據(jù)庫(kù)層面的保障,一致性的實(shí)現(xiàn)也需要應(yīng)用層面進(jìn)行保障墓懂。

實(shí)現(xiàn)一致性的措施包括:

保證原子性焰宣、持久性和隔離性,如果這些特性無(wú)法保證捕仔,事務(wù)的一致性也無(wú)法保證匕积。數(shù)據(jù)庫(kù)本身提供保障,例如不允許向整形列插入字符串值逻澳、字符串長(zhǎng)度不能超過(guò)列的限制等闸天。應(yīng)用層面進(jìn)行保障,例如如果轉(zhuǎn)賬操作只扣除轉(zhuǎn)賬者的余額斜做,而沒(méi)有增加接收者的余額,無(wú)論數(shù)據(jù)庫(kù)實(shí)現(xiàn)的多么完美湾揽,也無(wú)法保證狀態(tài)的一致瓤逼。總結(jié)

4. 下面總結(jié)一下 ACID 特性及其實(shí)現(xiàn)原理:

原子性:語(yǔ)句要么全執(zhí)行库物,要么全不執(zhí)行霸旗,是事務(wù)最核心的特性。
事務(wù)本身就是以原子性來(lái)定義的;實(shí)現(xiàn)主要基于 undo log戚揭。
持久性:保證事務(wù)提交后不會(huì)因?yàn)殄礄C(jī)等原因?qū)е聰?shù)據(jù)丟失;實(shí)現(xiàn)主要基于 redo log诱告。
隔離性:保證事務(wù)執(zhí)行盡可能不受其他事務(wù)影響;
一致性:事務(wù)追求的最終目標(biāo),一致性的實(shí)現(xiàn)既需要數(shù)據(jù)庫(kù)層面的保障民晒,也需要應(yīng)用層面的保障精居。
  InnoDB 默認(rèn)的隔離級(jí)別是 RR锄禽,RR 的實(shí)現(xiàn)主要基于鎖機(jī)制、數(shù)據(jù)的隱藏列靴姿、undo log 和類 next-key lock 機(jī)制沃但。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市佛吓,隨后出現(xiàn)的幾起案子宵晚,更是在濱河造成了極大的恐慌,老刑警劉巖维雇,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件淤刃,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡吱型,警方通過(guò)查閱死者的電腦和手機(jī)钝凶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)唁影,“玉大人耕陷,你說(shuō)我怎么就攤上這事【萆颍” “怎么了哟沫?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)锌介。 經(jīng)常有香客問(wèn)我嗜诀,道長(zhǎng),這世上最難降的妖魔是什么孔祸? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任隆敢,我火速辦了婚禮,結(jié)果婚禮上崔慧,老公的妹妹穿的比我還像新娘拂蝎。我一直安慰自己,他們只是感情好惶室,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布温自。 她就那樣靜靜地躺著,像睡著了一般皇钞。 火紅的嫁衣襯著肌膚如雪悼泌。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天夹界,我揣著相機(jī)與錄音馆里,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛鸠踪,可吹牛的內(nèi)容都是我干的丙者。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼慢哈,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蔓钟!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起卵贱,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤滥沫,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后键俱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體兰绣,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年编振,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了缀辩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡踪央,死狀恐怖臀玄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情畅蹂,我是刑警寧澤健无,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站液斜,受9級(jí)特大地震影響累贤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜少漆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一臼膏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧示损,春花似錦渗磅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至烛谊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間嘉汰,已是汗流浹背丹禀。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人双泪。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓持搜,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親焙矛。 傳聞我的和親對(duì)象是個(gè)殘疾皇子葫盼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

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