事務在當今的企業系統無處不在,即使在高并發環境下也可以提供數據的完整性。一個事務是一個隻包含所有讀/寫操作成功的集合。如下圖:
一個事務本質上有四個特點ACID:
原子性
原子性任務是一個獨立的操作單元,是一種要麼全部是,要麼全部不是的原子單位性的操作。
一緻性
一個事務可以封裝狀态改變(除非它是一個隻讀的)。事務必須始終保持系統處于一緻的狀态,不管在任何給定的時間并發事務有多少。
一緻性有下面特點:
在現實中,事務系統遭遇并發請求時,這種串行化是有成本的, Amdahl法則描述如下:它是描述序列串行執行和并發之間的關系。
“一個程序在并行計算情況下使用多個處理器所能提升的速度是由這個程序中串行執行部分的時間決定的。”
大多數數據庫管理系統選擇(默認情況下)是放寬一緻性,以達到更好的并發性。
隔離性
事務是并發控制機制,他們交錯使用時也能提供一緻性。隔離讓我們隐藏來自外部世界未提交的狀态變化,一個失敗的事務不應該破壞系統的狀态。隔離是通過用悲觀或樂觀鎖機制實現的。
耐久性
一個成功的事務将永久性地改變系統的狀态,所以在它結束之前,所有導緻狀态的變化都記錄在一個持久的事務日志中。如果我們的系統突然受到系統崩潰或斷電,那麼所有未完成已提交的事務可能會重演。
盡管一些數據庫系統提供多版本并發控制 MVCC, 他們的并發控制都是通過鎖完成,因此,鎖會增加執行的串行性,影響并發性。
SQL标準規定了四個隔離水平:
髒讀
髒讀發生在:當一個事務允許讀取一個被其他事務改變但是未提交的狀态時,這是因為并沒有鎖阻止讀取,如上圖,你看到第二個事務讀取了一個并不一緻的值,不一緻的意思是,這個值是無效的,因為修改這個值的第一個事務已經回滾,也就是說,第一個事務修改了這個值,但是未提交确認,卻被第二個事務讀取,第一個事務又放棄修改,悔棋了,而第二個事務就得到一個髒數據。
非重複讀
反複讀同一個數據卻得到不同的結果,這是因為在反複幾次讀取的過程中,數據被修改了,這就導緻我們使用了stale數據,這可以通過一個共享讀鎖來避免。這是隔離級别READ_COMMITTED會導緻可重複讀的原因。設置共享讀鎖也就是隔離級别提高到REPETABLE_READ。
Phantom 讀
當第二個事務插入一行記錄,而正好之前第一個事務查詢了應該包含這個新紀錄的數據,那麼這個查詢事務的結果裡肯定沒有包含這個剛剛新插入的數據,這時幻影讀發生了,通過變化鎖和predicate locking避免。
總結:READ_COMMITED 是比較正确的選擇,因為SERIALIZABLE雖然能在不同事務發生時避免stale數據,也就是避免上述丢失剛剛修改的數據,但是性能是最低的,因為是一種最大化的串行。
後期會分享更多devops和DBA内容,感興趣的朋友可以關注下!
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!