===========================================html
原文連接: 通俗理解數據庫隔離機制 轉載請註明出處!數據庫
===========================================緩存
在理解數據庫隔離機制的時候發現網上不少文章都是千篇一概,解釋語言太過於標準書面化,描述的晦澀難懂,因果關係模糊。在這裏將本身對隔離機制的理解描述一下,力爭作到可以經過淺顯的語言描述出來。
安全
數據庫隔離機制是對於多線程同時操做數據庫而言的。對於單線程操做數據庫不存在所謂的隔離,也不須要進行隔離。這裏須要注意一點【操做數據庫】這裏要注意區分這個操做是讀取或者修改已存在的數據,仍是插入刪除新的數據。多線程
數據庫隔離機制四種:post
一、未提交讀(Read Uncommitted)url
自定義名稱:修改級別隔離(只要修改了數據,則其餘事務就能夠看到)
spa
能夠理解爲:A事務只要修改了數據,不管有沒有提交,其餘事務都可以讀取到A事務修改後的結果。
線程
潛在問題【對於同一記錄進行修改操做】:A事務修改以後未提交,B事務讀取到修改以後的數據,而後在這個基礎上進行操做修改並提交。而後A提交失敗,數據回滾,則數據就出現異常。這就是所謂的髒讀。htm
解決方案:A事務提交以後B事務才能讀取到A修改以後的數據,不讓讀取修改但未提交的數據
二、提交讀(Read Committed)
自定義名稱:提交級別隔離(只有成功提交事務,則其餘事務纔可以看到)
能夠理解爲:A事務成功commit以後,其餘事務纔可以讀取到A提交事務以後的最新數據,不然只能讀取到A提交以前的原始數據。這樣就解決了髒讀問題。
潛在問題【對於同一記錄進行修改操做】:A事務開啓第一次讀取數據,而後B事務開啓對數據進行了修改並提交成功, 此時A事務尚未結束,又進行了一次讀操做,而後便發現A事務中的兩次讀取的數據不一致。這就是所謂的不可重複讀。同一個事務中兩次讀取的數據不同。【這裏有一個問題我也沒搞明白,爲何在同一個事務中我要對同一條記錄讀取兩次或者屢次呢?我讀一次存儲在緩存中不就能夠了?什麼狀況下會發生須要讀兩次的的狀況?應用場景有哪些?有理解的朋友還望告知!】
解決方案:在一個事務對該行數據進行操做的時候,其餘事務不容許進行修改。能夠理解爲添加一個行級別的鎖
三、可重複讀(Repeatable Read)
自定義名稱:事務級別隔離(A事務中的數據不會受B事務中的修改操做影響,即便B事務提交以後,A事務再次查詢的數據也不會發生變化)
能夠理解爲:在本身的事務中複製了一套相關的數據,該數據是私有的不受其餘事務的影響。所以能夠解決不可重複讀的問題。這裏雖然解決了不可重讀的問題,可是卻沒有解決數據覆蓋的問題,也就是B操做的數據是最原始的數據(和A未修改以前的數據同樣),而並非最新(A修改以後的數據)的數據。對於此隔離機制沒法解決這個問題,須要使用行級鎖來進行處理。
潛在問題【對於同表進行插入或刪除操做】:A事務插入/刪除了一條記錄,可是B事務中卻查詢不到插入的新記錄/依舊能查到刪除的記錄。這就是所謂的幻讀。幻讀是對於記錄條數而言的,不是針對於某一條記錄的數據而言的。這裏須要注意!
解決方案:在有事務對該表進行操做的時候,不容許其餘事務操做該表。添加表級鎖。
四、串行讀(Serializable)
自定義名稱:表級別隔離(不容許同時有多個事務操做該表)
能夠理解爲:全部的事務串行操做該數據表。這樣就能夠解決幻讀操做。
潛在問題:數據安全了 可是操做效率下降了。
解決方案:…………
四種隔離機制就是這樣子,潛在的問題分別爲:髒讀,不可重複讀,幻讀和效率低下。髒讀、幻讀和效率低下的問題都可以很好的理解,但是不可重複讀爲何也是個須要避免的問題呢?爲何在同一個事務中須要兩個讀取同一條數據呢?這個不太明白……
理解的時候不要看所謂的「讀未提交」、「提交讀」、「可重複讀」和「串行讀」,這只是描述了一種讀取方式,並不算是一種隔離機制(我的理解)。
------end