搜尋
首頁資料庫mysql教程如何理解資料庫事務隔離等級及髒讀、不可重複讀、幻讀

這篇文章帶給大家的內容是關於如何理解資料庫事務隔離等級及髒讀、不可重複讀、幻讀,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

一、資料庫事務正確執行的四個基本要素

1.1ACID原則。

  ACID原則是資料庫事務正常執行的四個基本要素,分別指原子性、一致性、獨立性及持久性。

  事務的原子性(Atomicity)是指一個事務要么全部執行,要么不執行,也就是說一個事務不可能只執行了一半就停止了,比如你從取款機取錢,這個事務可以分成兩個步驟:1劃卡,2出錢。不可能劃了卡,而錢卻沒出來,這兩步必須同時完成.要么就不完成。

  交易的一致性(Consistency)是指交易的運作並不會改變資料庫中資料的一致性。例如,完整性約束了a b=10,一個事務改變了a,那麼b也應該隨之改變。或者說,A給B轉帳300元錢,那麼A的帳戶就必須是減少300元錢,B的帳戶就必須是增加300元錢,不能說是增加或減少瞭如200元錢等,這裡符合事務的原子性,但是不符合交易的一致性。往實際業務中沒有這麼簡單,往是類似買東西扣庫存這類的邏輯,主表裡有庫存,庫存表裡有庫存,SKU表裡還有,然後就因為設計缺陷,就算加了事務還是出現了超賣、SKU庫存對不上總庫存的問題,這個就是一致性不滿足的了。

  獨立性(Isolation):事務的獨立性也有稱作隔離性,是指兩個以上的事務不會出現交錯執行的狀態,因為這樣可能會導致資料不一致。

  持久性(Durability):一旦交易提交或回滾,這個狀態都要持久化到資料庫中,不考慮隔離性會出現的讀取問題。


1.2髒讀、不可重複讀,幻讀。

  髒讀(Dirty read):在一個事務中讀取到另一個交易沒有提交的資料。例如,當一個事務正在存取數據,並且對數據進行了修改,而這種修改還沒有提交到資料庫中,這時,另一個事務也訪問這個數據,然後使用了這個數據。

  不可重複讀取(NonRepeatable Read):既不能讀到相同的資料內容。是指在一個事務內,多次讀同一數據,在這個事務還沒有結束時,另外一個事務也訪問該同一數據並且修改,那麼,在第一個事務中的兩次讀數據之間,由於第二個事務的修改,第一個事務兩次讀到的的資料可能是不一樣的。

  幻讀(Phantom Read):在一個交易中,兩次查詢的結果不一致(針對的insert操作) 。是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的資料進行了修改,這種修改涉及到表中的全部資料行。同時,第二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那麼,以後操作第一個事務的使用者發現表中還有沒有修改的資料行,就好像發生了幻覺一樣。
  例如,一個編輯人員更改作者提交的文檔,但當生產部門將其更改內容合併到該文檔的主複本時,發現作者已將未編輯的新材料添加到該文檔中。如果在編輯人員和生產部門完成原始文件的處理之前,任何人都無法將新資料新增至文件中,則可以避免該問題。


二、資料庫交易隔離等級

  資料庫交易的隔離等級有4個,由低到高依序為Read uncommitted(讀未提交)、Read committed(讀取提交) 、Repeatable read(可重複讀取)、Serializable(序列化),這四個層級可以逐一解決髒讀、不可重複讀取、幻讀這幾類問題。

2.1 Read uncommitted(讀未提交)

  公司發工資了,領導把5000元打到singo的帳號上,但是該事務並未提交,而singo剛好去查看帳戶,發現薪水到帳5000元整,非常高興。可是不幸的是,領導發現發給singo的工資金應該是2000元,於是迅速回滾了事務(將5000元回滾),修改金額後(修改為2000元),將事務提交,最後singo實際的薪水只有2000元,singo空歡喜一場。

  出現上述情況,即我們所說的髒讀,兩個並發的事務,“事務A:領導給singo發工資”,“事務B:singo查詢工資賬戶”,事務B讀取了事務A尚未提交的數據。

  當隔離等級設定為Read uncommitted(讀取未提交)時,就可能出現髒讀,如果我們此時將隔離等級提升為Read committed(讀取已提交),便可避免髒讀。


2.2 Read committed(讀取已提交)

#

  singo拿著工資卡去消費,系統讀取到卡里確實有2000元,而此時她的老婆也正好在網上轉賬,把singo工資卡的2000元轉到另一個賬戶,並在singo之前提交了事務,當singo扣款時,系統檢查到singo的工資卡已經沒有錢,扣款失敗,singo十分納悶,明明卡里有錢,到底是啥情況呢?

  出現上述情況,即我們所說的不可重複讀,兩個並發的事務,“事務A:singo消費”、“事務B:singo的老婆網上轉賬”,事務A事先讀取了數據,事務B緊接了更新了數據,並提交了事務,而事務A再次讀取該數據時,數據已經發生了改變。

  當隔離等級設定為Read committed(讀取已提交)時,避免了髒讀,但是可能會造成不可重複讀取(既不能讀到相同的資料內容)。

  大多數資料庫的預設等級就是Read committed(讀取已提交),例如Sql Server , Oracle,此時如果將隔離等級提升為Repeatable read(可重複讀取),則可以避免髒讀和不可重複讀的發生。


2.3 Repeatable read(可重複讀取)

  當隔離等級設定為Repeatable read(可重複讀取)時,可以避免無法重複讀取。當singo拿著薪資卡去消費時,一旦系統開始讀取薪資卡資訊(即事務開始),singo的老婆就不可能對該記錄進行修改,也就是singo的老婆不能在此時轉帳。

  (這裡兩個部落格舉得例子不一樣,請各位看官指明原因)或者說,有A、B兩個會話,分別開啟兩個事務,然後A向B轉了500元錢,A 提交事務,B再去查看,發現依舊是原錢數,B只能結束當前事務,在開啟一個新事務,才能查詢到數據的變化,這樣便避免了不可重複讀。如果我們設定了Seriizable(序列化),就等於鎖定表,某一時間內只允許一個事務存取該表。

  雖然Repeatable read避免了不可重複讀,但還有可能出現幻讀 。

  例如singo的老婆工作在銀行部門,她時常透過銀行內部系統查看singo的信用卡消費記錄。有一天,她正在查詢到singo當月信用卡的總消費金額(select sum(amount) from transaction where month = 本月)為80元,而singo此時正好在外面胡吃海塞後在收銀台買單,消費1000元,即新增了一張1000元的消費記錄(insert transaction … ),並提交了事務,隨後singo的老婆將singo當月信用卡消費的明細打印到A4紙上,卻發現消費總額為1080元,singo的老婆很詔異,以為出現了幻覺,幻讀就這樣產生了。

  註:Mysql的預設隔離等級就是Repeatable read。


2.4 Serializable(序列化)
  Serializable(序列化)是最高的事務隔離級別,同時代價也花費最高,性能很低,一般很少使用,在該層級下,事務順序執行,不僅可以避免髒讀、不可重複讀,還避免了幻讀。


三、總結

3.1 隔離等級與對應可能產生的問題表

#讀取已提交#不可能
隔離等級 髒讀(Dirty read) 不可重複讀取(NonRepeatable Read) 幻讀(Phantom Read)
#讀取未提交(Read uncommitted) 可能 可能 可能
(Read committed)
#可能######可能############################################# ##可重複讀取###(Repeatable read)######不可能######不可能######可能######################序列化###(Serializable)######不可能#######不可能#######不可能############

以上是如何理解資料庫事務隔離等級及髒讀、不可重複讀、幻讀的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
將用戶添加到MySQL:完整的教程將用戶添加到MySQL:完整的教程May 12, 2025 am 12:14 AM

掌握添加MySQL用戶的方法對於數據庫管理員和開發者至關重要,因為它確保數據庫的安全性和訪問控制。 1)使用CREATEUSER命令創建新用戶,2)通過GRANT命令分配權限,3)使用FLUSHPRIVILEGES確保權限生效,4)定期審計和清理用戶賬戶以維護性能和安全。

掌握mySQL字符串數據類型:varchar vs.文本與char掌握mySQL字符串數據類型:varchar vs.文本與charMay 12, 2025 am 12:12 AM

chosecharforfixed-lengthdata,varcharforvariable-lengthdata,andtextforlargetextfield.1)chariseffity forconsistent-lengthdatalikecodes.2)varcharsuitsvariable-lengthdatalikenames,ballancingflexibilitibility andperformance.3)

MySQL:字符串數據類型和索引:最佳實踐MySQL:字符串數據類型和索引:最佳實踐May 12, 2025 am 12:11 AM

在MySQL中處理字符串數據類型和索引的最佳實踐包括:1)選擇合適的字符串類型,如CHAR用於固定長度,VARCHAR用於可變長度,TEXT用於大文本;2)謹慎索引,避免過度索引,針對常用查詢創建索引;3)使用前綴索引和全文索引優化長字符串搜索;4)定期監控和優化索引,保持索引小巧高效。通過這些方法,可以在讀取和寫入性能之間取得平衡,提升數據庫效率。

mysql:如何遠程添加用戶mysql:如何遠程添加用戶May 12, 2025 am 12:10 AM

ToaddauserremotelytoMySQL,followthesesteps:1)ConnecttoMySQLasroot,2)Createanewuserwithremoteaccess,3)Grantnecessaryprivileges,and4)Flushprivileges.BecautiousofsecurityrisksbylimitingprivilegesandaccesstospecificIPs,ensuringstrongpasswords,andmonitori

MySQL字符串數據類型的最終指南:有效的數據存儲MySQL字符串數據類型的最終指南:有效的數據存儲May 12, 2025 am 12:05 AM

tostorestringsefliceflicyInmySql,ChooSetherightDataTypeBasedyOrneOrneEds:1)USEcharforFixed-LengthStstringStringStringSlikeCountryCodes.2)UseVarcharforvariable-lengtthslikenames.3)USETEXTCONTENT.3)

mysql blob vs.文本:為大對象選擇正確的數據類型mysql blob vs.文本:為大對象選擇正確的數據類型May 11, 2025 am 12:13 AM

選擇MySQL的BLOB和TEXT數據類型時,BLOB適合存儲二進制數據,TEXT適合存儲文本數據。 1)BLOB適用於圖片、音頻等二進制數據,2)TEXT適用於文章、評論等文本數據,選擇時需考慮數據性質和性能優化。

MySQL:我應該將root用戶用於產品嗎?MySQL:我應該將root用戶用於產品嗎?May 11, 2025 am 12:11 AM

No,youshouldnotusetherootuserinMySQLforyourproduct.Instead,createspecificuserswithlimitedprivilegestoenhancesecurityandperformance:1)Createanewuserwithastrongpassword,2)Grantonlynecessarypermissionstothisuser,3)Regularlyreviewandupdateuserpermissions

MySQL字符串數據類型說明了:選擇適合您數據的合適類型MySQL字符串數據類型說明了:選擇適合您數據的合適類型May 11, 2025 am 12:10 AM

mySqlStringDatatAtatPessHouldBechoseBasedondatActarActeristicsAndusecases:1)USEcharforFixed lengthStstringStringStringSlikeCountryCodes.2)usevarcharforvariable-lengtthslikeLikenames.3)usebarnionororvarinyorvarinyorvarybinarydatalgebenedaTalgeextocrabextrapon.4)

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具