數據庫若是支持事務,就要知足下面四個特性(ACID)。mysql
原子性(A:Atomicity)sql
在一個事務中,多個sql操做,要麼一塊兒成功(全部數據操做都成功),要麼一塊兒回滾(其中一個沒有成功,其餘數據操做一塊兒恢復到開始狀態)。數據庫
一致性(C:Consistency)服務器
數據修改前是準確的,修改後也要說準確的。指的是數據從一個一致性狀態,轉換到另外一種一致性的狀態。(例如:A和B總共有10個蘋果,A轉讓了幾個蘋果給B,事務結束後,A和B總共仍是10個蘋果)。併發
隔離性(I:Isolation)性能
當數據庫有多個事務一塊兒執行時,各個事務之間互相不影響,每一個事務感知不到有其餘的事務在執行。spa
持久性(D:Durability)blog
數據庫事務結束提交後,數據修改永久有效,即便數據庫重啓,遇到其餘問題關掉,再打開後,以前提交過的數據的修改仍是生效的(例如:程序執行數據的操做,事務提交後,忽然數據庫服務器斷電等緣由致使數據庫停掉不可用,恢復後,數據仍是修改後的狀態)。事務
讀未提交ci
兩個事務同時操做數據庫,其中一個事物修改數據庫後,沒有提交,另外一個事物能夠讀取到修改過的數據。
讀已提交
有兩個事務,第一個事務查詢一條數據,第二個事務修改這條數據提交後,第一個事務又查詢該數據,第一個事務先後兩次查詢的結果不一致。
可重複讀(mysql默認隔離級別,經過MVCC<Mutil-Version Concurrency Control>機制實現)
有兩個事務,第一個事務查詢一條數據,第二個事務修改這條數據提交後(出於性能考慮,使用了以樂觀鎖爲理論基礎的MVCC<多版本併發控制>來實現),第一個事務又查詢該數據,第一個事務先後兩次查詢的結果不致。
串行化(解決 幻讀 的問題)
可重複讀能夠限制兩個事務併發修改刪除數據致使先後查詢不一致的狀況,可是沒法限制insert(行鎖只能鎖住行,新增數據沒法限制)。
幻讀的案例場景:有兩個事務,第一個數據查詢列表數據條數,第二個事務新增數據到表中並提交事務,第一個事務又從新查詢數據條數,第一個事務先後兩次查詢的數據不一致。
串行化:有兩個事務,第一個事務查詢數據,第二個事務新增數據到表中,會報錯(表級鎖),不能插入數據,第一個事務再查詢數據,先後兩次結果一致。串行化併發低。
MVCC原理簡介:
經過事務id控制不一樣版本數據(由於經過事務id控制數據,因此下面數據中id也是會重複的),sql查詢的時候,後兩列隱藏列不會顯示。下列表格對應的事務開始順序與數字大小順序一致,最終全部事務一塊兒結束。(經過併發狀況簡單說明MVCC原理)
事務id=1插入數據;事務id=3插入數據;事務id=4刪除數據;事務id=5修改數據;表最終數據以下:
id 數據 更新事務ID(隱藏列) 刪除事務ID(隱藏列) 1 張三 1 4 2 小明 1 空 3 李四 1 空 4 王五 3 空 2 小明111 5 空
事務id=2,查詢全表數據,查詢數據以下:
start transaction; select * from a; //(1) select * from a; //(2) commit;
假設:
事務id=2中(1)查詢發生在事務id=1以後 ;
事務id=2中(2)查詢發生在事務id=3插入數據以後;
事務id=2兩次查詢結果都一
樣(經過事務id作了限制,只會查詢小於等於當前事務id的數據)
id 數據 更新事務ID(隱藏列) 刪除事務ID(隱藏列) 1 張三 1 空 2 小明 1 空 3 李四 1 空
假設:
事務id=2中(1)查詢發生在事務id=1以後 ;
事務id=2中(2)查詢發生在事務id=4刪除數據以後;
事務id=2兩次查詢結果都同樣(經過事務id作了限制,只會查詢小於等於當前事務id的數據)
id 數據 更新事務ID(隱藏列) 刪除事務ID(隱藏列) 1 張三 1 4 2 小明 1 空 3 李四 1 空
假設:
事務id=2中(1)查詢發生在事務id=1以後 ;
事務id=2中(2)查詢發生在事務id=5修改數據以後(修改也至關於插入一條數據,數據的事務id是不一樣的);
事務id=2兩次查詢結果都同樣(經過事務id作了限制,只會查詢小於等於當前事務id的數據)
數據 更新事務ID(隱藏列) 刪除事務ID(隱藏列) 1 張三 1 空 2 小明 1 空 3 李四 1 空