資料庫事務詳解

2021-09-09 06:24:50 字數 3143 閱讀 1092

事務(transaction)是在同乙個處理單元中,由一系列對資料進行訪問與更新的操作所組成的乙個基本程式執行邏輯單元。資料庫事務其實主要做了以下兩方面的事:

事務具有4個基本特徵,分別是:原子性(atomicity)、一致性(consistency)、隔離性(isolation)、永續性(duration),簡稱acid。

acid這4個特徵中,最難理解的是隔離性。在標準sql規範中,定義了4個事務隔離級別,不同的隔離級別對事務的處理不同。4個隔離級別分別是:讀未提及(read_uncommitted)、讀已提交(read_committed)、可重複讀(repeatable_read)、順序讀(serializable)。

資料庫在不同的隔離性級別下併發訪問可能會出現以下幾種問題:髒讀(dirty read)、不可重複讀(unrepeatable read)、幻讀(phantom read)。

1. 原子性(atomicity)

事務的原子性是指事務必須是乙個原子的操作序列單元。事務中包含的各項操作在一次執行過程中,只允許出現兩種狀態之一。

任何一項操作都會導致整個事務的失敗,同時其它已經被執行的操作都將被撤銷並回滾,只有所有的操作全部成功,整個事務才算是成功完成。

2. 一致性(consistency)

事務在完成時,必須使所有資料都保持一致狀態。也就是說乙個事務執行之前和執行之後都應該保持一致性狀態。銀行轉帳的例子:一共1000元,不管轉幾次總和都應該是1000元。滿足完整性的約束條件。

怎麼做到的:

資料庫機制層面

在乙個事務執行之前和執行之後,資料會符合你設定的約束(唯一約束、外來鍵約束、check 約束等)和觸發器設定。

業務層面

對於業務層面來說就是保持業務等一致性,就比如上面錢的總和要一致。

3. 隔離性(isolation)

事務的隔離性是指在併發環境中,併發的事務是互相隔離的,乙個事務的執行不能被其它事務干擾。也就是說,不同的事務併發操作相同的資料時,每個事務都有各自完整的資料空間。

乙個事務內部的操作及使用的資料對其它併發事務是隔離的,併發執行的各個事務是不能互相干擾的。

隔離性分4個級別,下面會介紹。

4. 永續性(duration)

事務的永續性是指事務一旦提交後,資料庫中的資料必須被永久的儲存下來。即使伺服器系統崩潰或伺服器宕機等故障。只要資料庫重新啟動,那麼一定能夠將其恢復到事務成功結束後的狀態。

1. 讀未提交(read_uncommitted)

讀未提及,該隔離級別允許髒讀取,其隔離級別是最低的。換句話說,如果乙個事務正在處理某一資料,並對其進行了更新,但同時尚未完成事務,因此還沒有提交事務;而以此同時,允許另乙個事務也能夠訪問該資料。

髒讀示例:

在事務a和事務b同時執行時可能會出現如下場景:

時間事務a(存款)

事務b(取款)

t1開始事務

——t2

——開始事務

t3——

查詢餘額(1000元)

t4——

取出1000元(餘額0元)

t5查詢餘額(0元)

——t6

——撤銷事務(餘額恢復1000元)

t7存入500元(餘額500元)

——t8

提交事務

——餘額應該為1500元才對。請看t5時間點,事務a此時查詢的餘額為0,這個資料就是髒資料,他是事務b還未提交時的查到資料。

2. 讀已提交(read_committed)

就是乙個事務要等另乙個事務提交後才能讀取資料。若有事務對資料進行更新(update)操作時,讀操作事務要等待這個更新操作事務提交後才能讀取資料,可以解決髒讀問題。

不可重複讀示例

可是解決了髒讀問題,但是還是解決不了可重複讀問題。

時間事務a(存款)

事務b(取款)

t1開始事務

——t2

——開始事務

t3——

查詢餘額(1000元)

t4查詢餘額(1000元)

——t5

——取出1000元(餘額0元)

t6——

提交事務

t7查詢餘額(0元)

——t8

提交事務

——如上圖,乙個事務範圍內兩個相同的查詢卻返回了不同資料,這就是不可重複讀。那怎麼解決可能的不可重複讀問題?

3. 可重複讀(repeatable_read)

就是在開始讀取資料(事務開啟)時,不再允許修改操作。重複讀可以解決不可重複讀問題。可重複讀就是保證在事務處理過程中,多次讀取同乙個資料時,該資料的值和事務開始時刻是一致的。不可重複讀對應的是修改,即update操作,我們不讓它upadte就ok了。但還是可能還會有幻讀問題。因為幻讀問題對應的是插入insert操作,而不是update操作。

幻讀幻讀就是指同樣的事務操作,在前後兩個時間段內執行對同乙個資料項的讀取,可能出現不一致的結果。

時間事務a(統計總存款)

事務b(存款)

t1開始事務

——t2

——開始事務

t3統計總存款(10000元)

——t4

——存入100元(insert一條資料)

t5——

提交事務

t6提交總存款(10100)

——t7

提交事務

——銀行工作人員在乙個事務中多次統計總存款時看到結果不一樣。如果要解決幻讀,那只能使用順序讀了。

4. 順序讀(serializable)

順序讀是最嚴格的事務隔離級別。它要求所有的事務排隊順序執行,即事務只能乙個接乙個地處理,不能併發。

事務隔離級別

髒 讀不可重複讀

幻 讀讀未提及(read_uncommitted)

允許允許

允許讀已提交(read_committed)

禁止允許

允許可重複讀(repeatable_read)

禁止禁止

允許順序讀(serializable)

禁止禁止

禁止

4種事務隔離級別從上往下,級別越高,併發性越差,安全性就越來越高。

一般資料預設級別是讀以提交或可重複讀。

參考:

資料庫事務詳解

事務 transaction 是由一系列對系統中資料進行訪問與更新的操作所組成的乙個程式執行邏輯單元。1.原子性 atomicity 事務的原子性是指事務必須是乙個原子的操作序列單元。事務中包含的各項操作在一次執行過程中,只允許出現兩種狀態之一。全部執行成功 全部執行失敗 任何一項操作都會導致整個事...

資料庫事務詳解

事務四特性 原子性是指事務包含的所有操作要麼全部成功,要麼全部失敗回滾,這和前面兩篇部落格介紹事務的功能是一樣的概念,因此事務的操作如果成功就必須要完全應用到資料庫,如果操作失敗則不能對資料庫有任何影響。一致性是指事務必須使資料庫從乙個一致性狀態變換到另乙個一致性狀態,也就是說乙個事務執行之前和執行...

資料庫事務詳解

從根本上理解mysql事務,是指作為單個邏輯工作單元執行的一系列操作,要麼成功完全地執行,要麼失敗全部回滾。最經典的例子 使用者a往 使用者b賬戶裡轉100塊錢。正常邏輯 首先使用者a賬戶裡扣除一百元,然後使用者b賬戶增加100元,則轉賬操作完成。這是正常情況,接下來再看看這種情況 使用者a賬戶裡扣...