久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      深入聊聊MySQL中的事務特性和實現(xiàn)原理

      本篇文章帶大家聊聊MySQL中的事務特性,介紹一下多版本并發(fā)控制MVCC實現(xiàn)原理,希望對大家有所幫助!

      深入聊聊MySQL中的事務特性和實現(xiàn)原理

      一、概念

      事務 一般指的是邏輯上的一組操作,或者作為單個邏輯單元執(zhí)行的一系列操作,一個事務中的所有操作會被封裝成一個不可分割的執(zhí)行單元,這個單元的所有操作要么全部執(zhí)行成功,要么全部執(zhí)行失敗,只要其中任意一個操作執(zhí)行失敗,整個事務就會執(zhí)行回滾操作。

      二、事務的特性以及類型介紹

      2.1 事務特性

      深入聊聊MySQL中的事務特性和實現(xiàn)原理

      原子性(atomicity)

      事務的原子性指的是構成事務的所有操作要么全部執(zhí)行成功,要么全部執(zhí)行是失敗。

      一致性(consistency)

      事務的一致性指的是事務執(zhí)行之前和執(zhí)行之后,數(shù)據(jù)始終處于一致的狀態(tài)。

      隔離性(isolation)

      事務的隔離性指的是并發(fā)執(zhí)行的兩個事務之間互不干擾,也就是說,一個事務執(zhí)行的過程中是無法看到其他事務運行過程的中間狀態(tài)的。

      ?‍注意:MySQL是通過鎖個MVCC機制來保證事務的隔離性。

      持久性(duration)

      事務的持久性指的是一旦事務被提交后,此事務對數(shù)據(jù)的更改操作會被持久化到數(shù)據(jù)庫中,并且不會被回滾。

      2.2 兩種事務類型介紹

      • 本地事務
      • 分布式事務

      本地事務

      通?;陉P系型數(shù)據(jù)庫控制的事務可以稱作為傳統(tǒng)事務或者本地事務。

      本地事務的執(zhí)行流程

      深入聊聊MySQL中的事務特性和實現(xiàn)原理

      • 客戶端開始事務操作之前,需要開啟一個連接回話;

      • 開始回話之后,客戶端發(fā)起開啟事務的指令;

      • 事務開始后,客戶端發(fā)送各種SQL語句處理數(shù)據(jù);

      • 正常情況下,客戶端會發(fā)起提交事務的指令,如果發(fā)生異常情況,客戶端會發(fā)起回滾事務命令;

      • 上述流程完成后,關閉會話。

      ✔本地事務是有資源管理器在本地進行管理的。

      本地事務的缺點在于:

      • 不具備分布式事務的處理能力
      • 一次事務過程只能連接一個支持事務的數(shù)據(jù)庫,既不能用于多個事務性數(shù)據(jù)庫。

      三、并發(fā)事務會帶來的哪些問題?

      深入聊聊MySQL中的事務特性和實現(xiàn)原理

      更新丟失(臟寫)

      當兩個會在兩個以上的事務同時操作同一行數(shù)據(jù),并給予最初選定的值更新該行數(shù)據(jù)時,視為事務之間是無法感知彼此的存在的,所以會出現(xiàn)最后的更新操作會覆蓋之前其他事務完成的更新操作。

      舉個例子:

      張三的賬戶為100元,當前有兩個事務:事務1和事務2,事務1是將張三賬戶余額增加100元,事務2是將張三余額增加200,起初事務1和事務2同時讀到張三的賬戶余額都是100元,然后事務1和事務2分別更新張三月,假設事務1先于事務2提交,但是最近兩個事務都提交后張三的余額為300元(正常情況應該是400元),也就是說:后提交的事務2覆蓋了事務1的更新操作,這就是所謂的更新丟失,更新丟失(臟寫)本質(zhì)上是寫操作的沖突,然而解決臟寫的方式是讓每個事務串行方式執(zhí)行,保證事務按照一定的順序執(zhí)行寫操作。

      深入聊聊MySQL中的事務特性和實現(xiàn)原理

      臟讀

      一個事務讀取到另一個事務未提交的數(shù)據(jù)。比如:事務1正在對張三的余額增加100元,在這個事務沒提交之前,另一個事務2讀取了正在修改的這條數(shù)據(jù),如果沒有事務的控制下,第二條事務就會讀取到?jīng)]有被提交的臟數(shù)據(jù),并且對臟數(shù)據(jù)叢下一步的處理,此時就會產(chǎn)生未提交數(shù)據(jù)的依賴關系,通常這種現(xiàn)象被稱為 臟讀,也就是說:臟讀是一個事務讀取了另一個事務沒提交的數(shù)據(jù)。

      深入聊聊MySQL中的事務特性和實現(xiàn)原理

      ?臟讀本質(zhì)上是讀寫操作的沖突,解決方法是先寫后讀,也就是寫完之后再讀。

      不可重復讀

      一個事務讀取了某些數(shù)據(jù),在一段時間后,這個事務再次讀取之前讀過的數(shù)據(jù),此時發(fā)現(xiàn)讀取的數(shù)據(jù)發(fā)生了變化,或者其中某些數(shù)據(jù)記錄已經(jīng)被刪除,這種現(xiàn)象被稱為:不可重復讀,即同一個事務,使用同樣的查詢語句,在不同時刻讀取到的結(jié)果不一致。

      不可重復讀的本質(zhì)上也是讀寫操作沖突,解決方法是先讀后寫,也就是讀完之后再寫。

      幻讀

      一個事務按照相同的查詢條件重新讀取之前讀過的數(shù)據(jù),此時發(fā)現(xiàn)其他事務插入了滿足當前查詢條件的新數(shù)據(jù),數(shù)據(jù)結(jié)果集變多,這種現(xiàn)象稱為幻讀,即一個事務兩次讀取一個范圍的數(shù)據(jù)記錄,兩次讀到的結(jié)果不同。

      幻讀的本質(zhì)上也是讀寫操作沖突,解決方法是先讀后寫,也就是讀完之后再寫。

      那到這里,很多小伙伴就有疑問,同樣本質(zhì)都是讀寫操作沖突,解決方法是先讀后寫,不可重復讀和幻讀到底有何區(qū)別?,我下面見簡單解釋一下:

      • 1️⃣ 不可重復讀的重點在于更新和刪除操作,而幻讀的重點在于插入操作。

      • 2️⃣ MySQL使用鎖機制實現(xiàn)事務的隔離級別時,在可重復讀隔離級別中,SQL語句第一個讀取到數(shù)據(jù)后,會將相應的數(shù)據(jù)加鎖,使得其他事務無法修改和刪除這些數(shù)據(jù),通過鎖的方式實現(xiàn)可重復讀。但是這種方法無法對新數(shù)據(jù)的插入加鎖,如果事務1讀取了數(shù)據(jù),或者修改和刪除了數(shù)據(jù),事務2還可以進行插入操作,導致事務1莫名其妙地多了一條之前沒有的數(shù)據(jù),這就是幻讀。

      • 3️⃣ 所以,幻讀是無法通過鎖機制來避免,需要使用串行化的事務隔離級別,但是這種事務隔離級別會大大降低數(shù)據(jù)庫的并發(fā)能力。

      ✔MySQL是通過MVCC(多版本并發(fā)控制)機制來避免不可重復讀和幻讀的。

      四、MySQL事務的隔離級別

      深入聊聊MySQL中的事務特性和實現(xiàn)原理

      使用下面的命令可以查詢?nèi)旨墑e和會話級別的事務隔離級別:

      # 默認數(shù)據(jù)庫的事務隔離級別為:可重復讀(REPEATABLE-READ) SELECT @@global.tx_isolation; SELECT @@session.tx_isolation; SELECT @@tx_isolation;
      登錄后復制

      深入聊聊MySQL中的事務特性和實現(xiàn)原理

      五、多版本并發(fā)控制MVCC

      Multi-Version Concurrency Control多版本并發(fā)控制,MVCC是一種并發(fā)控制的方法,一般在數(shù)據(jù)庫管理系統(tǒng)中,實現(xiàn)對數(shù)據(jù)庫的并發(fā)訪問。

      MVCC比鎖的優(yōu)勢

      可以將MVCC看成行級別鎖的一種妥協(xié),它在許多情況下避免了使用鎖,同時可以提供更小的開銷。根據(jù)實現(xiàn)的不同,它可以允許非阻塞式讀,在寫操作進行時只鎖定必要的記錄。

      MVCC的實現(xiàn)原理

      MVCC的是通過保存數(shù)據(jù)澡某個時間點的快照來實現(xiàn)的,也就是說,不管事務執(zhí)行多長的時間,每個事務看到的數(shù)據(jù)都是一致的。根據(jù)事務的開始時間不同,每個事務對同一張表,同一時刻看到的數(shù)據(jù)可能是不一樣的。InnonDB主要通過為每一行記錄添加兩個額外的隱藏的值來實現(xiàn)MVCC,這兩個值一個記錄這行數(shù)據(jù)何時被創(chuàng)建,另外一個記錄這行數(shù)據(jù)何時過期(或者被刪除)。但是InnoDB并不存儲這些事件發(fā)生時的 實際時間 ,相反它只存儲這些事件發(fā)生時的系統(tǒng) 版本號(version) 。這是一個隨著事務的創(chuàng)建而不斷增長的數(shù)字。每個事務在事務開始時會記錄它自己的系統(tǒng)版本號。每個查詢必須去檢查每行數(shù)據(jù)的版本號與事務的版本號是否相同。

      《高性能MySQL》書籍中介紹到:

      MVCC只在REPEATABLE READREAD COMMITTIED兩個隔離級別下工作,其他兩個隔離級別都和MVCC不兼容,因為READ UNCOMMITTED總是讀取最新的數(shù)據(jù)行,而不符合當前事務版本數(shù)據(jù)行,而SERIALIZABLE串行化隔離級別則會對所有讀取的行都加鎖。

      接下來舉個例子說明在可重復讀事務隔離級別下,MVCC機制是如何完成增刪改查操作的。

      • 查詢操作(SELECT)

      在查詢操作中,InnoDB存儲引擎跟根據(jù)以下兩個條件查詢對應的行記錄,只有滿足對應條件才會被返回:

      1️⃣ 只查找不晚于當前事務版本的數(shù)據(jù)行,也就是說,InnoDB存儲引擎只會查找版本號小于或者等于當前事務版本的數(shù)據(jù)行,這些數(shù)據(jù)行要么在該事務開始前就存在,要么就是事務本身插入或者更新的行。
      2️⃣ 對于數(shù)據(jù)刪除,數(shù)據(jù)行刪除的版本要么還沒有被定義,要么大于當前事務的版本號,只有這樣才能確保事務讀到的行,在事務開始前并沒有被刪除。

      舉個例子,存在 事務A事務B 兩個事務,事務A中存在兩套相同的SELECT語句,事務B存在一條UPDATE語句,事務A 的第一條查詢語句在事務B提交之前執(zhí)行,第二條查詢語句在 事務B 提交之后執(zhí)行,事務A 如下所示:

      -- 事務A操作 START TRANSACTION; SELECT * FROM account WHERE id = 1;     //在事務B提交之前執(zhí)行 SELECT * FROM account WHERE id = 1;     //在事務B提交之后執(zhí)行 COMMIT;
      登錄后復制

      事務B:

      -- 事務B操作 START TRANSACTION; UPDATE account SET balance = balance+100 WHERE id = 1; COMMIT;
      登錄后復制

      ✔結(jié)論:如果沒有使用MVCC機制,則事務A中的第一條SELECT語句讀取的數(shù)據(jù)是修改前的數(shù)據(jù),而第二條SELECT語句讀取的是修改后的數(shù)據(jù),兩次讀取的數(shù)據(jù)不一致,想想,那不就亂了嗎?? 如果使用了MVCC機制,無論事務B如何修改數(shù)據(jù),事務A的兩條查詢語句的到的結(jié)果始終是一致的。

      • 插入操作(SELECT)

      在插入操作中,InnoDB會將新插入的每一條行記錄的當前系統(tǒng)版本包保存為行版本號。

      比如:向account表插入一條數(shù)據(jù),同時MVCC的兩個版本號分別為create_versiondelete_versioncreate_version代表創(chuàng)建行的版本號,delete_version代表刪除行的版本號,另外還有一個事務ID字段,如下面所示:

      INSERT INTO account(id, name, balance) values(1001, 'austin', 100);
      登錄后復制

      對應的版本號信息如下表:

      id name balance transaction_id create_version delete_version
      1001 austin 100 1 1 未定義

      可以看出,當向數(shù)據(jù)表新增記錄時,需要設置保存行的版本號,而刪除行的版本號未定義。

      • 更新操作(SELECT)

      在更新操作中,InnoDB存儲引擎會插入一行新記錄,并保存當前系統(tǒng)的版本號為新記錄行的版本號,同時保存當前系統(tǒng)的版本號到原來數(shù)據(jù)行作為刪除標識。比如:將account數(shù)據(jù)表中id為1001的用戶賬戶月增加100元,對應SQL如下:

      UPDATE account SET balance = balance+100 WHERE id = 1001;
      登錄后復制

      執(zhí)行SQL, 在MVCC機制下的更新操作如下表所示:

      id name balance transaction_id create_version delete_version
      1001 austin 100 1 1 2
      1001 austin 200 2 2 未定義

      可以明顯看出,執(zhí)行更新操作時,MVCC機制是先將原來的數(shù)據(jù)復制一份,將balance字段增加100后,再講create_version字段的值設置為當前系統(tǒng)的版本號,而delete_version字段的值未定義。

      注意的是:原來的行會被復制到Undo Log中。

      • 刪除操作(SELECT)

      在刪除操作中,InnoDB存儲引擎會保存刪除的每一個行記錄當前的系統(tǒng)版本號,作為刪除標識。比如:刪除account數(shù)據(jù)表中id為1001的數(shù)據(jù),SQL如下所示:

      DELETE FROM account WHERE id = 1001;
      登錄后復制

      對應MVCC機制下的刪除操作如下表所示:

      id name balance transaction_id create_version delete_version
      1001 austin 200 3 2 3

      可以看出,當刪除數(shù)據(jù)表數(shù)據(jù)行時,MVCC機制會將當前系統(tǒng)的版本號寫入刪除數(shù)據(jù)行版本字段delete_version中,以此來表示當前數(shù)據(jù)行已經(jīng)被刪除。

      六、總結(jié)

      本文主要講述了事務的特性、類型和本地事務和分布式事務的區(qū)別,通過不同的示例解釋并發(fā)事務帶來的更新丟失、臟讀、不可重復讀、幻讀的問題,同時介紹了多版本并發(fā)控制MVCC的實現(xiàn)原理,如果文章對你有幫助,感謝點贊?+評論?+收藏❤,我是:?‍?austin流川楓,我們下期見!

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號