SQL隔離級別

什麼是SQL的隔離級別呢?舉個例子來說吧。
事例1、
假設有用戶A和用戶B,他們對同一張innodb表進行如下操作:
①、同時開啓一個事務:
②、用戶A向表中插入一條數據。
③、用戶B查詢表中的數據。
④、同時提交事務。

那麼,當用戶A插入數據之後,用戶B再去表中查詢數據時,用戶A剛纔插入的那條數據對用戶B這次的查詢是否可見,便成爲隔離級別。

SQL標準定義了四個隔離級別:

一、READ UNCOMMITTED(讀取未提交內容)
在這個隔離級別下,當在事務a中修改數據後,雖然事務a還沒有提交,但其他事務也能讀取到事務a中修改的內容。就比如上面說的那個列子,如果是在這個隔離級別下,用戶B就能讀取到用戶A插入的那條數據。

在這個隔離級別下,最容易出現“髒讀”這個問題。比如事例1中,當用戶A插入數據後,提交事務的時候出現問題,然後事務回滾,把用戶A插入的那條數據刪除,但用戶B卻讀到了那條數據。

二、READ COMMITTED(讀取提交內容)
在這個隔離級別下,當事務a中修改數據後,只要事務a還沒有提交,就不能被其他事務讀取到修改的內容。但在一個事務中,任何一次查詢,都是獲取已經提交事務的所有變化。
比如以下例子:
事例2、
①、用戶A開啓一個事務。
②、用戶B向表1中插入一條數據x,提交事務。
③、用戶A查詢表1中的數據。
④、用戶B向表1中插入一條數據y,提交事務。
⑤、用戶A查詢表1中的數據。
⑥、用戶A提交事務。
那麼,對用戶A的這次事務來說,前後兩次的查詢結果是不同的。這也是這個隔離級別的問題所在。

三、REPEATABLE READ(可重讀)
這個隔離級別就是爲了解決上一個隔離級別而生的。在這個隔離級別下,在一個事務中的查詢,只能讀取到事務開始時,表中的數據。比如事例2中,在用戶A開啓事務的過程中,用戶B向表1中插入了兩條數據,但在這一隔離級別下,用戶A的兩次查詢都讀取不到用戶B插入的數據。

然而,這個隔離級別就會出現“幻讀”的問題。比如如下列子:
事例 3、
①、用戶A開啓一個事務。
②、用戶B向表1中插入一條數據x,提交事務。
③、用戶A查詢表1中的數據,判斷是否存在數據x。
④、用戶A發現表1中沒有數據x,然後也插入數據x。
⑥、用戶A提交事務。
這時候,如果表中有唯一建,那麼用戶A插入數據x時,就會報錯。這裏,就把第三步,用戶A查詢表中數據,判斷是否存在數據x的結果稱爲“幻讀”。

四、SERIALIZABLE(可串行化)
這個隔離級別是最高的隔離級別,用於解決幻讀問題。在這個隔離級別下,它會強制的對事務進行排序,使事務之前不可能衝突,從而解決幻讀問題。所謂的排序,是指:爲每個事務所讀取的行加上鎖。在這一級別下,會造成大量的超時現象和鎖競爭。

發佈了33 篇原創文章 · 獲贊 3 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章