acid嘛,原子性(atomicity)、一致性(consistency)、隔離性(isolation)、永續性(durability)
根據定義,原子性是指乙個事務是乙個不可分割的工作單位,其中的操作要麼都做,要麼都不做。即要麼轉賬成功,要麼轉賬失敗,是不存在中間的狀態!
如果無法保證原子性會怎麼樣?
ok,就會出現資料不一致的情形,a賬戶減去50元,而b賬戶增加50元操作失敗。系統將無故丟失50元~
根據定義,隔離性是指多個事務併發執行的時候,事務內部的操作與其他事務是隔離的,併發執行的各個事務之間不能互相干擾。
如果無法保證隔離性會怎麼樣?
ok,假設a賬戶有200元,b賬戶0元。a賬戶往b賬戶轉賬兩次,金額為50元,分別在兩個事務中執行。如果無法保證隔離性,會出現下面的情形
如圖所示,如果不保證隔離性,a扣款兩次,而b只加款一次,憑空消失了50元,依然出現了資料不一致的情形!
根據定義,永續性是指事務一旦提交,它對資料庫的改變就應該是永久性的。接下來的其他操作或故障不應該對其有任何影響。
如果無法保證永續性會怎麼樣?
在mysql中,為了解決cpu和磁碟速度不一致問題,mysql是將磁碟上的資料載入到記憶體,對記憶體進行操作,然後再回寫磁碟。好,假設此時宕機了,在記憶體中修改的資料全部丟失了,永續性就無法保證。
設想一下,系統提示你轉賬成功。但是你發現金額沒有發生任何改變,此時資料出現了不合法的資料狀態,我們將這種狀態認為是資料不一致的情形。
根據定義,一致性是指事務執行前後,資料處於一種合法的狀態,這種狀態是語義上的而不是語法上的。
那什麼是合法的資料狀態呢?
ok,這個狀態是滿足預定的約束就叫做合法的狀態,再通俗一點,這狀態是由你自己來定義的。滿足這個狀態,資料就是一致的,不滿足這個狀態,資料就是不一致的!
如果無法保證一致性會怎麼樣?
例一:a賬戶有200元,轉賬300元出去,此時a賬戶餘額為-100元。你自然就發現了此時資料是不一致的,為什麼呢?因為你定義了乙個狀態,餘額這列必須大於0。
例二:a賬戶200元,轉賬50元給b賬戶,a賬戶的錢扣了,但是b賬戶因為各種意外,餘額並沒有增加。你也知道此時資料是不一致的,為什麼呢?因為你定義了乙個狀態,要求a+b的餘額必須不變。
ok,這個問題分為兩個層面來說。
從資料庫層面,資料庫通過原子性、隔離性、永續性來保證一致性。也就是說acid四大特性之中,c(一致性)是目的,a(原子性)、i(隔離性)、d(永續性)是手段,是為了保證一致性,資料庫提供的手段。資料庫必須要實現aid三大特性,才有可能實現一致性。例如,原子性無法保證,顯然一致性也無法保證。
但是,如果你在事務裡故意寫出違反約束的**,一致性還是無法保證的。例如,你在轉賬的例子中,你的**裡故意不給b賬戶加錢,那一致性還是無法保證。因此,還必須從應用層角度考慮。
從應用層面,通過**判斷資料庫資料是否有效,然後決定回滾還是提交資料!
ok,是利用innodb的undo log。
undo log名為回滾日誌,是實現原子性的關鍵,當事務回滾時能夠撤銷所有已經成功執行的sql語句,他需要記錄你要回滾的相應日誌資訊。
例如(1)當你delete一條資料的時候,就需要記錄這條資料的資訊,回滾的時候,insert這條舊資料
(2)當你update一條資料的時候,就需要記錄之前的舊值,回滾的時候,根據舊值執行update操作
(3)當年insert一條資料的時候,就需要這條記錄的主鍵,回滾的時候,根據主鍵執行delete操作
undo log記錄了這些回滾需要的資訊,當事務執行失敗或呼叫了rollback,導致事務需要回滾,便可以利用undo log中的資訊將資料回滾到修改之前的樣子。
ps:具體的undo log日誌長啥樣,這個可以寫一篇文章了。而且寫出來,看的人也不多,姑且先這麼簡單的理解吧。
ok,是利用innodb的redo log。
正如之前說的,mysql是先把磁碟上的資料載入到記憶體中,在記憶體中對資料進行修改,再刷回磁碟上。如果此時突然宕機,記憶體中的資料就會丟失。
怎麼解決這個問題?
簡單啊,事務提交前直接把資料寫入磁碟就行啊。
這麼做有什麼問題?
只修改乙個頁面裡的乙個位元組,就要將整個頁面刷入磁碟,太浪費資源了。畢竟乙個頁面16kb大小,你只改其中一點點東西,就要將16kb的內容刷入磁碟,聽著也不合理。
畢竟乙個事務裡的sql可能牽涉到多個資料頁的修改,而這些資料頁可能不是相鄰的,也就是屬於隨機io。顯然操作隨機io,速度會比較慢。
於是,決定採用redo log解決上面的問題。當做資料修改的時候,不僅在記憶體中操作,還會在redo log中記錄這次操作。當事務提交的時候,會將redo log日誌進行刷盤(redo log一部分在記憶體中,一部分在磁碟上)。當資料庫宕機重啟的時候,會將redo log中的內容恢復到資料庫中,再根據undo log和binlog內容決定回滾資料還是提交資料。
採用redo log的好處?
其實好處就是將redo log進行刷盤比對資料頁刷盤效率高,具體表現如下
redo log體積小,畢竟只記錄了哪一頁修改了啥,因此體積小,刷盤快。
redo log是一直往末尾進行追加,屬於順序io。效率顯然比隨機io來的快。
問題四: mysql怎麼保證隔離性的?
ok,利用的是鎖和mvcc機制。還是拿轉賬例子來說明,有乙個賬戶表如下
表名t_balance
其中id是主鍵,user_id為賬戶名,balance為餘額。還是以轉賬兩次為例,如下圖所示
至於mvcc,即多版本併發控制(multi version concurrency control),乙個行記錄資料有多個版本對快照資料,這些快照資料在undo log中。
如果乙個事務讀取的行正在做delele或者update操作,讀取操作不會等行上的鎖釋放,而是讀取該行的快照版本。
由於mvcc機制在可重複讀(repeateable read)和讀已提交(read commited)的mvcc表現形式不同,就不贅述了。
但是有一點說明一下,在事務隔離級別為讀已提交(read commited)時,乙個事務能夠讀到另乙個事務已經提交的資料,是不滿足隔離性的。但是當事務隔離級別為可重複讀(repeateable read)中,是滿足隔離性的。
MySQL 事務概念 ACID
事務是用來保證業務操作的完整性 整個業務要麼全部成功,要麼全部失敗,不允許部分成功,部分失敗 a 原子性 c 一致性 i 隔離性 d 永續性 讀未提交 read uncommitted 讀已提交 read commited 可重複讀 repeatable read 序列化讀 serlalizable...
MySQL 事務的ACID特性
事務的acid特性 原子性 atomicity 乙個事務是乙個不可分割的最小工作單位,事務中的所有操作要麼都做,要麼都不做。一致性 consistency 事務前後資料的完整性必須保持一致.事務必須是使資料庫從乙個一致性狀態變到另乙個一致性狀態,一致性與原子性是密切相關的。隔離性 isolation...
Mysql的ACID 事務併發 事務隔離級別
目錄 一 事務的基本要素 acid a atomicity,即原子性 c consistency,即一致性 i isolation,即隔離性 d durability,即永續性 二 事務的併發問題 1.髒讀 2.不可重複讀 3.幻讀 三 mysql的事務隔離級別 事務開始後的所有操作,要麼全部完成,...