91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何在Mysql中實現事務ACID

發布時間:2021-06-01 17:58:55 來源:億速云 閱讀:190 作者:Leah 欄目:MySQL數據庫

這期內容當中小編將會給大家帶來有關如何在Mysql中實現事務ACID,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

原子性

根據定義,原子性是指一個事務是一個不可分割的工作單位,其中的操作要么都做,要么都不做。即要么轉賬成功,要么轉賬失敗,是不存在中間的狀態!

如果無法保證原子性會怎么樣?

OK,就會出現數據不一致的情形,A賬戶減去50元,而B賬戶增加50元操作失敗。系統將無故丟失50元~

隔離性

根據定義,隔離性是指多個事務并發執行的時候,事務內部的操作與其他事務是隔離的,并發執行的各個事務之間不能互相干擾。

如果無法保證隔離性會怎么樣?

OK,假設A賬戶有200元,B賬戶0元。A賬戶往B賬戶轉賬兩次,金額為50元,分別在兩個事務中執行。如果無法保證隔離性,會出現下面的情形

如何在Mysql中實現事務ACID

如圖所示,如果不保證隔離性,A扣款兩次,而B只加款一次,憑空消失了50元,依然出現了數據不一致的情形!

ps:可能有細心的讀者已經發現了,mysql中是依靠鎖來解決隔離性問題。嗯,我們后面來說明。

持久性

根據定義,持久性是指事務一旦提交,它對數據庫的改變就應該是永久性的。接下來的其他操作或故障不應該對其有任何影響。

如果無法保證持久性會怎么樣?

在Mysql中,為了解決CPU和磁盤速度不一致問題,Mysql是將磁盤上的數據加載到內存,對內存進行操作,然后再回寫磁盤。好,假設此時宕機了,在內存中修改的數據全部丟失了,持久性就無法保證。

設想一下,系統提示你轉賬成功。但是你發現金額沒有發生任何改變,此時數據出現了不合法的數據狀態,我們將這種狀態認為是數據不一致的情形。

一致性

根據定義,一致性是指事務執行前后,數據處于一種合法的狀態,這種狀態是語義上的而不是語法上的。
那什么是合法的數據狀態呢?

oK,這個狀態是滿足預定的約束就叫做合法的狀態,再通俗一點,這狀態是由你自己來定義的。滿足這個狀態,數據就是一致的,不滿足這個狀態,數據就是不一致的!

如果無法保證一致性會怎么樣?

例一:A賬戶有200元,轉賬300元出去,此時A賬戶余額為-100元。你自然就發現了此時數據是不一致的,為什么呢?因為你定義了一個狀態,余額這列必須大于0。

例二:A賬戶200元,轉賬50元給B賬戶,A賬戶的錢扣了,但是B賬戶因為各種意外,余額并沒有增加。你也知道此時數據是不一致的,為什么呢?因為你定義了一個狀態,要求A+B的余額必須不變。

實戰解答

問題一:Mysql怎么保證一致性的?

OK,這個問題分為兩個層面來說。

從數據庫層面,數據庫通過原子性、隔離性、持久性來保證一致性。也就是說ACID四大特性之中,C(一致性)是目的,A(原子性)、I(隔離性)、D(持久性)是手段,是為了保證一致性,數據庫提供的手段。數據庫必須要實現AID三大特性,才有可能實現一致性。例如,原子性無法保證,顯然一致性也無法保證。

但是,如果你在事務里故意寫出違反約束的代碼,一致性還是無法保證的。例如,你在轉賬的例子中,你的代碼里故意不給B賬戶加錢,那一致性還是無法保證。因此,還必須從應用層角度考慮。

從應用層面,通過代碼判斷數據庫數據是否有效,然后決定回滾還是提交數據!

問題二: Mysql怎么保證原子性的?

OK,是利用Innodb的undo log。

undo log名為回滾日志,是實現原子性的關鍵,當事務回滾時能夠撤銷所有已經成功執行的sql語句,他需要記錄你要回滾的相應日志信息。

例如

  • (1)當你delete一條數據的時候,就需要記錄這條數據的信息,回滾的時候,insert這條舊數據

  • (2)當你update一條數據的時候,就需要記錄之前的舊值,回滾的時候,根據舊值執行update操作

  • (3)當年insert一條數據的時候,就需要這條記錄的主鍵,回滾的時候,根據主鍵執行delete操作

undo log記錄了這些回滾需要的信息,當事務執行失敗或調用了rollback,導致事務需要回滾,便可以利用undo log中的信息將數據回滾到修改之前的樣子。

ps:具體的undo log日志長啥樣,這個可以寫一篇文章了。而且寫出來,看的人也不多,姑且先這么簡單的理解吧。

問題三: Mysql怎么保證持久性的?

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來的快。

ps:不想具體去談redo log具體長什么樣,因為內容太多了。

問題四: Mysql怎么保證隔離性的?

OK,利用的是鎖和MVCC機制。還是拿轉賬例子來說明,有一個賬戶表如下

表名t_balance

iduser_idbalance
1A200
2B0

其中id是主鍵,user_id為賬戶名,balance為余額。還是以轉賬兩次為例,如下圖所示

如何在Mysql中實現事務ACID

至于MVCC,即多版本并發控制(Multi Version Concurrency Control),一個行記錄數據有多個版本對快照數據,這些快照數據在undo log中。

如果一個事務讀取的行正在做DELELE或者UPDATE操作,讀取操作不會等行上的鎖釋放,而是讀取該行的快照版本。

由于MVCC機制在可重復讀(Repeateable Read)和讀已提交(Read Commited)的MVCC表現形式不同,就不贅述了。

但是有一點說明一下,在事務隔離級別為讀已提交(Read Commited)時,一個事務能夠讀到另一個事務已經提交的數據,是不滿足隔離性的。但是當事務隔離級別為可重復讀(Repeateable Read)中,是滿足隔離性的。

上述就是小編為大家分享的如何在Mysql中實現事務ACID了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

尚志市| 芮城县| 依兰县| 文安县| 滨州市| 平谷区| 马龙县| 石泉县| 绍兴县| 靖西县| 呼和浩特市| 布拖县| 佛学| 浦东新区| 昌吉市| 南华县| 平泉县| 郯城县| 资中县| 伊宁市| 会宁县| 彭泽县| 马鞍山市| 株洲县| 永福县| 澄迈县| 延安市| 黄骅市| 宜良县| 上思县| 鄂伦春自治旗| 龙海市| 五峰| 广宁县| 昆山市| 镇坪县| 桦甸市| 廉江市| 通道| 山阳县| 武邑县|