之前我們談到過,資料庫通過調整事務之間的隔離級別來提高事務的性能,
那么接下來,我們來首先說說事務之間可能互相遇到的問題,
大家都知道事務只有提交后,才會真正的持久化到硬碟,倘若出現出現了回滾的操作,則事務所有操作的影響都會被回退掉,那么假若事務在執行程序中,其他事務讀取到了當前的操作結果,但是當前事務后邊回滾了,那么其他事務相當于讀取到了錯誤的資料,
舉個例子
老板告訴HR,技術員工從下個月開始漲工資,技術小A從小道訊息得知后,非常開心,準備把自己的單車換成摩托,后邊老板發現公司的債務堆積嚴重,告知HR取消該加薪計劃,得知真相的小A眼淚流下淚,只能含著淚去找摩托店老板退貨,
流程如下圖:

理論上小A等員工不應該從側面提前獲知公司的加薪計劃,而應該在公司正式發文后(事務提交后)才可獲知,這個問題就是我們常說的臟讀,此時的隔離級別我們稱之為讀未提交,也就是說還沒有正式公布的資料,可以被提前獲知到,(防盜連接:本文首發自http://www.cnblogs.com/jilodream/ )
如何解決這個問題呢?
公司特別進行了申明,任何未經公司正式發文的訊息,全部為不實訊息,大家不可以信賴,出現任何問題后果自負,大家只能相信眼見為實的那些訊息,這種隔離級別我們稱之為讀已提交,也就是只能讀到公司正式發文的資訊,對于那些未通過正式發文的訊息,直接無視掉,
問題好像已經解決了,
年會前公司正式發文,由于今年業績成長明顯,經討論, 全員加薪,
小A看了看自己騎了兩年的單車,決定換一輛摩托,正所謂搏一搏單車變摩托,
于是小A興沖沖的跑到摩托車行,預定了自己中意已久的摩托,
然而接下來小A在參加年會的程序中,老總在會議上特別宣布,由于上一年公司業績的特別突出,經過公司董事會的宣布,包括小A在內的所有員工,特別增發配股,
小A看了看微信已經給摩托車老板轉發的定金,又看了看最新的路虎,陷入的沉思,正所謂賭一賭摩托變路虎,年會結束后,小A火速聯系摩托車老板,一哭二鬧的總算把押金退了,去隔壁的4S店下單了路虎,
流程如下圖:

對于這種每次讀取到待遇都不一樣,導致處理程序中出現了錯誤的處理的場景,我們稱之為不可重復讀,啥意思呢?也就是說即使公司正式發文后(提交后),也可能存在不確定性,因為公司可能反復提交資料,導致你拿到的資料仍然是臟資料,甚至你已經根據歷史資料進行了錯誤的處理,此時的隔離級別我們稱之為讀已提交,
那么怎么解決這個不可重復讀的問題呢?
也就是你操作期間,其他人不能改資料,很簡單,你用什么資料鎖住什么資料就好了,如果你需要根據薪酬要做出消費的判斷,那么只要鎖住薪酬就好了,
這樣好像問題已經解決了,但是通過一系列操作預訂完路虎的你,回家發現,當初私房錢買的位元幣,現在已經漲到3萬美金了,折合下來資產都過億了,(防盜連接:本文首發自http://www.cnblogs.com/jilodream/ )望著一串你的小屏手機都快顯示不下的數字,你再次陷入沉思,從沉思緩過來后,你撥通了路虎店的電話,又是一頓一哭二鬧三上吊,你去了旁邊的瑪莎拉蒂店下了訂單,
整體的流程如下:

為啥明明已經鎖定了薪酬,可是收入卻仍然無情的增長,
原因很簡單,你只鎖定住了既有的資料,來自單位的薪酬,沒有鎖住外界新增的資料,導致讀到的資料仍然不夠準確,無法做出正確的處理,這種例外場景我們稱之為幻讀,也就是因為新增資料導致的讀不一致性,而當前的這種隔離級別稱之為可重復讀,也就是我們可以反復的讀取之前已經讀取到的資料,但是新增的資料,我們仍然可能會讀取到,讀不一致性仍然存在
如何解決幻讀的問題呢?
答案很簡單,還是加鎖,之前加鎖是對某些已經存在的資料加鎖,現在加鎖,是對全域加鎖,誰要操作,誰獲取到全域的鎖,(防盜連接:本文首發自http://www.cnblogs.com/jilodream/ )至此也就不存在并發場景了,也就更不存在并發問題了,這種隔離級別我們稱之為串行化,
至于這幾種隔離級別在innodb中是如何實作的,確實是比較復雜,一兩句話難以說清,我會在后文中專門講解
下邊我們總結一下前文所提到的概念:
1、 臟讀
讀到了其他事務未提交的資料,(也就是臟頁中的資料,這個后文中我會專門講解)
2、 不可重復讀
在事務中每次讀取到的資料是別人已經提交的資料,但是由于存在并發修改(update delele),每次讀取到的資料不一致
3、 幻讀
對于新插入的資料造成的讀不一致性,我們稱之為幻讀
這三個問題都屬于存在并發事務時,資料的前后讀不一致的問題,解決辦法就是通過資料庫的不同隔離機制,(防盜連接:本文首發自http://www.cnblogs.com/jilodream/ )來規避掉這些問題,
1、 讀未提交 Read Uncommitted
事務未提交的資料修改,對其他事務也是可見的
未解決臟讀,不可重復讀,幻讀
2、 讀已提交 Read Committed
一個事務開始后,只能看到已經提交的事務做出的修改
解決臟讀,未解決不可重復讀,幻讀
3、 可重復讀 Repeatable Read
一個事務開始后,對于已經查詢出的資料,再次反復查詢獲取到的資料是一樣的
解決了臟讀,不可重復讀,未解決幻讀
這里要特別注意下,可重復讀級別盡管不要求解決幻讀問題,但是innodb存盤引擎卻不存在該問題,這個我會再接下來的博客中專門解釋該問題
4、 串行化 Serializable
最高級別,強制事務進行串行操作
解決了所有資料庫并發問題

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/244666.html
標籤:其他
上一篇:資料庫事務以及事務的四個特性
下一篇:Cannot delete or update a parent row: a foreign key constraint fails(解決外鍵關聯無法洗掉)
