===========================================
原文鏈接: 通俗理解數據庫隔離機制 轉載請注明出處!
===========================================
在理解數據庫隔離機制的時候發現網上很多文章都是千篇一律,解釋語言太過於標准書面化,描述的晦澀難懂,因果關系模糊。在這里將自己對隔離機制的理解描述一下,力爭做到能夠通過淺顯的語言描述出來。
數據庫隔離機制是對於多線程同時操作數據庫而言的。對於單線程操作數據庫不存在所謂的隔離,也不需要進行隔離。這里需要注意一點【操作數據庫】這里要注意區分這個操作是讀取或者修改已存在的數據,還是插入刪除新的數據。
數據庫隔離機制四種:
1、未提交讀(Read Uncommitted)
自定義名稱:修改級別隔離(只要修改了數據,則其他事務就可以看到)
可以理解為:A事務只要修改了數據,無論有沒有提交,其他事務都能夠讀取到A事務修改后的結果。
潛在問題【對於同一記錄進行修改操作】:A事務修改之后未提交,B事務讀取到修改之后的數據,然后在這個基礎上進行操作修改並提交。然后A提交失敗,數據回滾,則數據就出現異常。這就是所謂的臟讀。
解決方案:A事務提交之后B事務才能讀取到A修改之后的數據,不讓讀取修改但未提交的數據
2、提交讀(Read Committed)
自定義名稱:提交級別隔離(只有成功提交事務,則其他事務才能夠看到)
可以理解為:A事務成功commit之后,其他事務才能夠讀取到A提交事務之后的最新數據,否則只能讀取到A提交之前的原始數據。這樣就解決了臟讀問題。
潛在問題【對於同一記錄進行修改操作】:A事務開啟第一次讀取數據,然后B事務開啟對數據進行了修改並提交成功, 此時A事務還沒有結束,又進行了一次讀操作,然后便發現A事務中的兩次讀取的數據不一致。這就是所謂的不可重復讀。同一個事務中兩次讀取的數據不一樣。【這里有一個問題我也沒搞明白,為什么在同一個事務中我要對同一條記錄讀取兩次或者多次呢?我讀一次存儲在緩存中不就可以了?什么情況下會發生需要讀兩次的的情況?應用場景有哪些?有理解的朋友還望告知!】
解決方案:在一個事務對該行數據進行操作的時候,其他事務不允許進行修改。可以理解為添加一個行級別的鎖
3、可重復讀(Repeatable Read)
自定義名稱:事務級別隔離(A事務中的數據不會受B事務中的修改操作影響,即使B事務提交之后,A事務再次查詢的數據也不會發生變化)
可以理解為:在自己的事務中復制了一套相關的數據,該數據是私有的不受其他事務的影響。因此可以解決不可重復讀的問題。這里雖然解決了不可重讀的問題,但是卻沒有解決數據覆蓋的問題,也就是B操作的數據是最原始的數據(和A未修改之前的數據一樣),而並不是最新(A修改之后的數據)的數據。對於此隔離機制無法解決這個問題,需要使用行級鎖來進行處理。
潛在問題【對於同表進行插入或刪除操作】:A事務插入/刪除了一條記錄,但是B事務中卻查詢不到插入的新記錄/依舊能查到刪除的記錄。這就是所謂的幻讀。幻讀是對於記錄條數而言的,不是針對於某一條記錄的數據而言的。這里需要注意!
解決方案:在有事務對該表進行操作的時候,不允許其他事務操作該表。添加表級鎖。
4、串行讀(Serializable)
自定義名稱:表級別隔離(不允許同時有多個事務操作該表)
可以理解為:所有的事務串行操作該數據表。這樣就可以解決幻讀操作。
潛在問題:數據安全了 但是操作效率降低了。
解決方案:…………
四種隔離機制就是這樣子,潛在的問題分別為:臟讀,不可重復讀,幻讀和效率低下。臟讀、幻讀和效率低下的問題都能夠很好的理解,可是不可重復讀為什么也是個需要避免的問題呢?為什么在同一個事務中需要兩個讀取同一條數據呢?這個不太明白……
理解的時候不要看所謂的“讀未提交”、“提交讀”、“可重復讀”和“串行讀”,這只是描述了一種讀取方式,並不算是一種隔離機制(個人理解)。
------end
