資料庫的隔離級別 「可重複讀」的誤區

2022-04-11 13:38:21 字數 6569 閱讀 7456

1樓:豆豆漆

第一步:開始事務1,並進行查詢

第二步:開啟事務2進行修改

第三步:將事務2提交

第四步:重新整理資料庫得到資料是

第五步:再次執行事務1中的查詢

此時d的值還是45d。

證明你的結論1正確

2樓:

2 可重複讀隔離級別是最嚴格的隔離級別。在該隔離級別下,一個事務的影響完全與其他併發事務隔離,髒讀、不可重複的讀、幻像讀現象都不會發生。當使用可重複讀隔離級別時,在事務執行期間會鎖定該事務以任何方式引用的所有行。

因此,如果在同一個事務中發出同一個select語句兩次或更多次,那麼產生的結果資料集總是相同的。因此,使用可重複讀隔離級別的事務可以多次檢索同一行集,並對它們執行任意操作,直到提交或回滾操作終止該事務。但是,在事務存在期間,不允許其他事務執行會影響這個事務正在訪問的任何行的插入、更新或刪除操作。

為了確保這種行為不會發生,鎖定該事務所引用的每一行-- 而不是僅鎖定被實際檢索或修改的那些行。因此,如果一個事務掃描了1000行,但只檢索10行,那麼它所掃描的1000行(而不僅是被檢索的10行)都會被鎖定。

mysql 隔離級別設定為什麼比較好

3樓:龍氏風采

一、首先什麼是事務?

事務是應用程式中一系列嚴密的操作,所有操作必須成功完成,否則在每個操作中所作的所有更改都會被撤消。也就是事務具有原子性,一個事務中的一系列的操作要麼全部成功,要麼一個都不做。

事務的結束有兩種,當事務中的所以步驟全部成功執行時,事務提交。如果其中一個步驟失敗,將發生回滾操作,撤消撤消之前到事務開始時的所以操作。

二、事務的 acid

事務具有四個特徵:原子性( atomicity )、一致性( consistency )、隔離性( isolation )和持續性( durability )。這四個特性簡稱為 acid 特性。

1 、原子性。事務是資料庫的邏輯工作單位,事務中包含的各操作要麼都做,要麼都不做2 、一致性。事 務執行的結果必須是使資料庫從一個一致性狀態變到另一個一致性狀態。

因此當資料庫只包含成功事務提交的結果時,就說資料庫處於一致性狀態。如果資料庫系統 執行中發生故障,有些事務尚未完成就被迫中斷,這些未完成事務對資料庫所做的修改有一部分已寫入物理資料庫,這時資料庫就處於一種不正確的狀態,或者說是 不一致的狀態。

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

4 、持續性。也稱永久性,指一個事務一旦提交,它對資料庫中的資料的改變就應該是永久性的。接下來的其它操作或故障不應該對其執行結果有任何影響。

三、mysql的四種隔離級別

sql標準定義了4類隔離級別,包括了一些具體規則,用來限定事務內外的哪些改變是可見的,哪些是不可見的。低階別的隔離級一般支援更高的併發處理,並擁有更低的系統開銷。

read uncommitted(讀取未提交內容)

在該隔離級別,所有事務都可以看到其他未提交事務的執行結果。本隔離級別很少用於實際應用,因為它的效能也不比其他級別好多少。讀取未提交的資料,也被稱之為髒讀(dirty read)。

read committed(讀取提交內容)

這是大多數資料庫系統的預設隔離級別(但不是mysql預設的)。它滿足了隔離的簡單定義:一個事務只能看見已經提交事務所做的改變。

這種隔離級別 也支援所謂的不可重複讀(nonrepeatable read),因為同一事務的其他例項在該例項處理其間可能會有新的commit,所以同一select可能返回不同結果。

repeatable read(可重讀)

這是mysql的預設事務隔離級別,它確保同一事務的多個例項在併發讀取資料時,會看到同樣的資料行。不過理論上,這會導致另一個棘手的問題:幻讀 (phantom read)。

簡單的說,幻讀指當使用者讀取某一範圍的資料行時,另一個事務又在該範圍內插入了新行,當使用者再讀取該範圍的資料行時,會發現有新的「幻影」 行。innodb和falcon儲存引擎通過多版本併發控制(mvcc,multiversion concurrency control)機制解決了該問題。

serializable(可序列化)

這是最高的隔離級別,它通過強制事務排序,使之不可能相互衝突,從而解決幻讀問題。簡言之,它是在每個讀的資料行上加上共享鎖。在這個級別,可能導致大量的超時現象和鎖競爭。

這四種隔離級別採取不同的鎖型別來實現,若讀取的是同一個資料的話,就容易發生問題。例如:

髒讀(drity read):某個事務已更新一份資料,另一個事務在此時讀取了同一份資料,由於某些原因,前一個rollback了操作,則後一個事務所讀取的資料就會是不正確的。

不可重複讀(non-repeatable read):在一個事務的兩次查詢之中資料不一致,這可能是兩次查詢過程中間插入了一個事務更新的原有的資料。

幻讀(phantom read):在一個事務的兩次查詢中資料筆數不一致,例如有一個事務查詢了幾列(row)資料,而另一個事務卻在此時插入了新的幾列資料,先前的事務在接下來的查詢中,就會發現有幾列資料是它先前所沒有的。

在mysql中,實現了這四種隔離級別,分別有可能產生問題如下所示:

四、測試mysql的隔離級別

下面,將利用mysql的客戶端程式,我們分別來測試一下這幾種隔離級別。

測試資料庫為demo,表為test;表結構:

兩個命令列客戶端分別為a,b;不斷改變a的隔離級別,在b端修改資料。

(一)、將a的隔離級別設定為read uncommitted(未提交讀)a:啟動事務,此時資料為初始狀態

b:啟動事務,更新資料,但不提交

a:再次讀取資料,發現資料已經被修改了,這就是所謂的「髒讀」

b:回滾事務

a:再次讀資料,發現資料變回初始狀態

經過上面的實驗可以得出結論,事務b更新了一條記錄,但是沒有提交,此時事務a可以查詢出未提交記錄。造成髒讀現象。未提交讀是最低的隔離級別。

(二)、將客戶端a的事務隔離級別設定為read committed(已提交讀)a:啟動事務,此時資料為初始狀態

b:啟動事務,更新資料,但不提交

a:再次讀資料,發現資料未被修改

b:提交事務

a:再次讀取資料,發現資料已發生變化,說明b提交的修改被事務中的a讀到了,這就是所謂的「不可重複讀」

經過上面的實驗可以得出結論,已提交讀隔離級別解決了髒讀的問題,但是出現了不可重複讀的問題,即事務a在兩次查詢的資料不一致,因為在兩次查詢之間事務b更新了一條資料。已提交讀只允許讀取已提交的記錄,但不要求可重複讀。

(三)、將a的隔離級別設定為repeatable read(可重複讀)a:啟動事務,此時資料為初始狀態

b:啟動事務,更新資料,但不提交

a:再次讀取資料,發現資料未被修改

b:提交事務

a:再次讀取資料,發現資料依然未發生變化,這說明這次可以重複讀了b:插入一條新的資料,並提交

a:再次讀取資料,發現資料依然未發生變化,雖然可以重複讀了,但是卻發現讀的不是最新資料,這就是所謂的「幻讀」

a:提交本次事務,再次讀取資料,發現讀取正常了由以上的實驗可以得出結論,可重複讀隔離級別只允許讀取已提交記錄,而且在一個事務兩次讀取一個記錄期間,其他事務部的更新該記錄。但該事務不要求與其他事務可序列化。

例如,當一個事務可以找到由一個已提交事務更新的記錄,但是可能產生幻讀問題(注意是可能,因為資料庫對隔離級別的實現有所差別)。像以上的實驗,就沒有出現資料幻讀的問題。

(四)、將a的隔離級別設定為可序列化(serializable)a:啟動事務,此時資料為初始狀態

b:發現b此時進入了等待狀態,原因是因為a的事務尚未提交,只能等待(此時,b可能會發生等待超時)a:提交事務

b:發現插入成功

serializable完全鎖定欄位,若一個事務來查詢同一份資料就必須等待,直到前一個事務完成並解除鎖定為止。是完整的隔離級別,會鎖定對應的資料**,因而會有效率的問題。

mysql 事物隔離級別rr還是rc好

4樓:智者總要千慮

資料庫事務的四個隔離級別,mysql在哪一個級別

mysql的innodb引擎對四個隔離級別都支援,

預設是repeated read。

5樓:地瓜說機

1. 資料庫事務acid特性

資料庫事務的4個特性:

原子性(atomic): 事務中的多個操作,不可分割,要麼都成功,要麼都失敗; all or nothing.

一致性(consistency): 事務操作之後, 資料庫所處的狀態和業務規則是一致的; 比如a,b賬戶相互轉賬之後,總金額不變;

隔離性(isolation): 多個事務之間就像是序列執行一樣,不相互影響;

永續性(durability): 事務提交後被持久化到永久儲存.

2. 隔離性

其中 隔離性 分為了四種:

read uncommitted:可以讀取未提交的資料,未提交的資料稱為髒資料,所以又稱髒讀。此時:幻讀,不可重複讀和髒讀均允許;

read committed:只能讀取已經提交的資料;此時:允許幻讀和不可重複讀,但不允許髒讀,所以rc隔離級別要求解決髒讀;

repeatable read:同一個事務中多次執行同一個select,讀取到的資料沒有發生改變;此時:允許幻讀,但不允許不可重複讀和髒讀,所以rr隔離級別要求解決不可重複讀;

serializable: 幻讀,不可重複讀和髒讀都不允許,所以serializable要求解決幻讀;

3. 幾個概念

髒讀:可以讀取未提交的資料。rc 要求解決髒讀;

不可重複讀:同一個事務中多次執行同一個select, 讀取到的資料發生了改變(被其它事務update並且提交);

可重複讀:同一個事務中多次執行同一個select, 讀取到的資料沒有發生改變(一般使用mvcc實現);rr各級級別要求達到可重複讀的標準;

幻讀:同一個事務中多次執行同一個select, 讀取到的資料行發生改變。也就是行數減少或者增加了(被其它事務delete/insert並且提交)。

serializable要求解決幻讀問題;

這裡一定要區分 不可重複讀 和 幻讀:

不可重複讀的重點是修改:

同樣的條件的select, 你讀取過的資料, 再次讀取出來發現值不一樣了

幻讀的重點在於新增或者刪除:

同樣的條件的select, 第1次和第2次讀出來的記錄數不一樣

從結果上來看, 兩者都是為多次讀取的結果不一致。但如果你從實現的角度來看, 它們的區別就比較大:

對於前者, 在rc下只需要鎖住滿足條件的記錄,就可以避免被其它事務修改,也就是 select for update, select in share mode; rr隔離下使用mvcc實現可重複讀;

對於後者, 要鎖住滿足條件的記錄及所有這些記錄之間的gap,也就是需要 gap lock。

而ansi sql標準沒有從隔離程度進行定義,而是定義了事務的隔離級別,同時定義了不同事務隔離級別解決的三大併發問題:

isolation level

dirty read

unrepeatable read

phantom read

read uncommitted

yesyes

yesread committed

noyes

yesread repeatable

nono

yesserializable

nono

no參見:你真的明白事務的隔離性嗎? (姜承堯)

4. 資料庫的預設隔離級別

除了mysql預設採用rr隔離級別之外,其它幾大資料庫都是採用rc隔離級別。

但是他們的實現也是極其不一樣的。oracle僅僅實現了rc 和 serializable隔離級別。預設採用rc隔離級別,解決了髒讀。

但是允許不可重複讀和幻讀。其serializable則解決了髒讀、不可重複讀、幻讀。

mysql的實現:mysql預設採用rr隔離級別,sql標準是要求rr解決不可重複讀的問題,但是因為mysql採用了gap lock,所以實際上mysql的rr隔離級別也解決了幻讀的問題。那麼mysql的serializable是怎麼回事呢?

其實mysql的serializable採用了經典的實現方式,對讀和寫都加鎖。

5. mysql 中rc和rr隔離級別的區別

mysql資料庫中預設隔離級別為rr,但是實際情況是使用rc 和 rr隔離級別的都不少。好像**、網易都是使用的 rc 隔離級別。那麼在mysql中 rc 和 rr有什麼區別呢?

我們該如何選擇呢?為什麼mysql將rr作為預設的隔離級別呢?

5.1 rc 與 rr 在鎖方面的區別

1> 顯然 rr 支援 gap lock(next-key lock),而rc則沒有gap lock。因為mysql的rr需要gap lock來解決幻讀問題。而rc隔離級別則是允許存在不可重複讀和幻讀的。

所以rc的併發一般要好於rr;

2> rc 隔離級別,通過 where 條件過濾之後,不符合條件的記錄上的行鎖,會釋放掉(雖然這裡破壞了「兩階段加鎖原則」);但是rr隔離級別,即使不符合where條件的記錄,也不會是否行鎖和gap lock;所以從鎖方面來看,rc的併發應該要好於rr;另外 insert into t select ... from s where 語句在s表上的鎖也是不一樣的,參見下面的例子2;

資料庫多表合併的問題,資料庫 多個使用者的資料合併到同一個表好還是分散到多個表上好?

簡單點說,每個中國人都有一個身份證號碼,而且這個身份證號碼一定能找到你 那麼現在我們建立表1 身份證號碼,姓名,性別,年齡,戶籍地,名族,家庭關係 現在你上班了,需要到單位報到,單位的hr肯定會要你的身份證號碼,那是為什麼呢?因為單位要建立自己的資料庫 現在我們建立表2 身份證號碼,工作經歷,學習經...

資料庫與資料結構的區別有哪些,資料庫與資料結構的區別?

資料庫相當於容器資料結構相當於往容器裡放東西方式和取東西方式沒有資料結構容器裡東西 資料 會雜亂無章取出來也麻煩 1 資料儲存層 資料儲存設計到資料庫的概念和資料庫語言,這方面不一定要深鑽研,但至少要理解資料的儲存方式,資料的基本結構和資料型別。sql查詢語言必不可少,精通最好。可從常用的selec...

資料分析和資料庫的關係是什麼,資料庫分析的原理是什麼?

可以這麼理解,資料庫是用來儲存資料的,資料分析是把儲存好的資料通過一系列的資料分析方法進行處理來得出你想要知道的問題結論。資料庫分析的原理是什麼?大資料 資料分析和資料探勘的區別是什麼?區別 大資料 是網際網路的海量資料探勘,而資料探勘更多是針對內部企業行業小眾化的資料探勘,資料分析就是進行做出針對...