序言:以下內容講的是mysql資料庫的原理,是mysql內部實現的,基本不用人工**干預
事務的:原子性、一致性、分離性、永續性
事物(transaction)是由一些列操作序列構成的執行單元,這些單元要麼都做,要麼不做,是乙個不可分割的工作單元。
資料庫事物的四個基本性質(acid)
1.原子性(atomicity)
指的是事物中包含的所有操作要麼全做,要麼全不做(all or none)。
例如銀行取款事務分為2個步驟(1)存摺減款(2)提取現金。不可能存摺減款,卻沒有提取現金。2個步驟必須同時完成或者都不完成。
2.一致性(consistency)
在事物開始以前,資料庫處於一致性的狀態,事物結束後,資料庫也必須處於一致性的狀態。
拿銀行轉賬來說,一致性要求事務的執行不應改變a、b 兩個賬戶的金額總和。如果沒有這種一致性要求,轉賬過程中就會發生錢無中生有,或者不翼而飛的現象。事務應該把資料庫從乙個一致性狀態轉換到另外乙個一致性狀態。
3.隔離性(isolation)
分離性指併發的事務是相互隔離的。即乙個事務內部的操作及正在操作的資料必須封鎖起來,不被其它企圖進行修改的事務看到。假如併發交叉執行的事務沒有任何控制,操縱相同的共享物件的多個併發事務的執行可能引起異常情況。
對於任何一對事務t1和t2,在事務t1看來,t2要麼在t1開始之前執行,要麼在t1完成之後才開始執行,這樣,每個事務都感覺不到系統中有併發事務執行。
4.永續性(durability)
永續性意味著當系統或介質發生故障時,確保已提交事務的更新不能丟失。即一旦乙個事務提交,dbms保證它對資料庫中資料的改變應該是永久性的,即對已提交事務的更新能恢復。永續性通過資料庫備份和恢復來保證。
多個事務同時訪問資料庫時候,會發生下列 問題,包括3類資料 問題(髒讀,不可重複讀,幻讀)
1,髒讀(dirty read)
a事務讀取b事務尚未提交的更改資料,並在這個資料基礎上操作。如果b事務回滾,那麼a事務讀到的資料根本不是合法的,稱為髒讀。
2,不可重複讀(unrepeatable read)
a事務讀取了b事務已經提交的更改(或刪除)資料。比如a事務第一次讀取資料,然後b事務更改該資料並提交,a事務再次讀取資料,兩次讀取的資料不一樣。
3,幻讀(phantom read)
a事務讀取了b事務已經提交的新增資料。注意和不可重複讀的區別,這裡是新增,不可重複讀是更改(或刪除)。
共享鎖和排它鎖
為了解決併發問題,資料庫系統引入鎖機制。
基本的封鎖型別有兩種: 排它鎖(exclusive locks 簡記為x鎖) 和 共享鎖(share locks 簡記為s鎖)。
排它鎖又稱為寫鎖。若事務t對資料物件a加上x鎖,則只允許t讀取和修改a,其它任何事務都不能再對a加任何型別的鎖,直到t釋放a上的鎖。這就保證了其它事務在t釋放a上的鎖之前不能再讀取和修改a。
共享鎖又稱為讀鎖。若事務t對資料物件a加上s鎖,則事務t可以讀a但不能修改a,其它事務只能再對a加s鎖,而不能加x鎖,直到t釋放a上的s鎖。這就保證了其它事務可以讀a,但在t釋放a上的s鎖之前不能對a做任何修改。
隔離級別
在運用 排他鎖 和 共享鎖 對資料物件加鎖時,還需要約定一些規則,例如何時申請 排他鎖 或 共享鎖、持鎖時間、何時釋放等。稱這些規則為 隔離級別。
資料庫事務的隔離級別有4種,由低到高分別為read uncommitted 、read committed 、repeatable read 、serializable
read uncommitted【讀未提交資料】:允許所有事務讀取未被其他事務提交的資料修改。會導致髒讀、不可重複讀和幻讀的問題的出現。
read committed【讀已提交資料】:只允許事務讀取已經被其他事務提交的資料修改。oracle和sql server預設的級別,可以避免髒讀,但不可重複讀和幻讀問題仍然會出現。
repeatable read【可重讀】:是mysql的預設事務隔離級別,它確保同一事務的多個例項在併發讀取資料時,會看到同樣的資料行。但幻讀問題未解除。
serializable【可序列化】:最高的隔離級別,它通過強制事務排序,使之不可能相互衝突,從而解決幻讀問題。一般通過共享讀鎖實現。在這個級別,可能導致大量的超時現象和鎖競爭。
資料庫中,通常預設隔離級別是「可重讀」,在預設的事務隔離級別下:insert,update,delete用的是排他鎖, 會等待事務完成。通常情況下可以把隔離級別設為repeatable read,它能避免髒讀、不可重複讀,而且有較好的併發效能。
為了資料庫的良好效能,而又不想使用高的隔離級別(serializable【可序列化】)解決幻讀問題,採用mvcc或者next-key 鎖解決幻讀問題
1,mvcc ( multi-version concurrency control )多版本併發控制
在快照讀的情況下(即普通的select),mysql innodb就是通過mvcc來解決幻讀問題:通過為每一行記錄新增兩個額外的隱藏的值來實現mvcc,這兩個值乙個記錄這行資料何時被建立,另外乙個記錄這行資料何時過期(或者被刪除)。但是innodb並不儲存這些事件發生時的實際時間,相反它只儲存這些事件發生時的系統版本號。這是乙個隨著事務的建立而不斷增長的數字。每個事務在事務開始時會記錄它自己的系統版本號。每個查詢必須去檢查每行資料的版本號與事務的版本號是否相同。讓我們來看看當隔離級別是repeatable read時這種策略是如何應用到特定的操作的
innodb會根據以下兩個條件檢查每行記錄:
innodb只會查詢版本早於當前事務版本的資料行(也就是,行的系統版本號小於或等於事務的系統版本號),這樣可以確保事務讀取的行,要麼是在事務開始前已經存在的,要麼是事務自身插入或者修改過的.
行的刪除版本要麼未定義,要麼大於當前事務版本號(這可以確保事務讀取到的行,在事務開始之前未被刪除),
只有條件1、2同時滿足的記錄,才能返回作為查詢結果.
2,next-key 鎖
在當前讀的情況下(update , insert ,delete ,select xx from xx for update , in share mode)情況下,用next-key 鎖解決幻讀問題,具體參考我的另外一篇文章《mysql innodb的死鎖問題》
資料庫事務
事件是訪問並可能更新各種資料項的乙個程式執行單元。事件由事務開始與事務結束之間執行的全體操作組成。為了保證資料完整性,資料庫系統需要維護事務的以下性質 原子性 atomicity 事務中的操作要麼全部成功,要麼全部失敗。一致性 consistency 事務執行前後要保持資料庫的一致性。隔離性 iso...
資料庫 事務
資料庫事務 database transaction 是指作為單個邏輯工作單元執行的一系列操作。事務處理可以確保除非事務性單元內的所有操作都成功完成,否則不會永久更新面向資料的資源。通過將一組相關操作組合為乙個要麼全部成功要麼全部失敗的單元,可以簡化錯誤恢復並使應用程式更加可靠。乙個邏輯工作單元要成...
資料庫事務
這段時間面試,由於基礎不是特別好,遇到一些要筆試的公司。就會表示出來 今天有人問我,資料庫事務 是什麼。我只感覺十分熟悉。但是又說不出所以然。回來找了一下,現在整理記錄 1 定義 資料庫事務 database transaction 是指作為單個邏輯工作單元執行的一系列操作。事務處理可以確保除非事務...