mysql k,mysql事务有关概念-怀念K.Dures
在最近的項目中由于涉及財務轉賬所以自然應用到mysql的事務處理,在業務邏輯設計之初就是在事務中處理提現的申請記錄以及賬戶余額的凍結,然而在并發的情況下,會出現‘臟讀’,看到這個單詞還是默默的來了一句‘我艸’,想想當年du lei si課堂上講transaction已過去4年,還是有點感慨,tmd,學過的東西終于在現實當中遇到了,可是渣渣我早已忘記怎么解決這種問題,經過幾次百度后問題基本解決。僅以此文記錄mysql事務有關概念,懷念K.Dures。
在并發情景下的事務中,要通過鎖機制控制并發帶來的臟讀,不可重復讀,幻讀的問題;
首先來明確MySQL InnoDB事務隔離級別
MySQLInnoDB事務的隔離級別有四級,默認是“可重復讀”(REPEATABLE READ)。
1)未提交讀(READUNCOMMITTED)。另一個事務修改了數據,但尚未提交,而本事務中的SELECT會讀到這些未被提交的數據(臟讀)(隔離級別最低,并發性能高)。
2)提交讀(READCOMMITTED)。本事務讀取到的是最新的數據(其他事務提交后的)。問題是,在同一個事務里,前后兩次相同的SELECT會讀到不同的結果(不重復讀)。會出現不可重復讀、幻讀問題(鎖定正在讀取的行)
3)可重復讀(REPEATABLEREAD)。在同一個事務里,SELECT的結果是事務開始時時間點的狀態,因此,同樣的SELECT操作讀到的結果會是一致的。但是,會有幻讀現象(稍后解釋)。會出幻讀(鎖定所讀取的所有行)。
4)串行化(SERIALIZABLE)。讀操作會隱式獲取共享鎖,可以保證不同事務間的互斥(鎖表)。
四個級別逐漸增強,每個級別解決一個問題。
1)臟讀:另一個事務修改了數據,但尚未提交,而本事務中的SELECT會讀到這些未被提交的數據。
首先區分臟頁和臟數據
臟頁是內存的緩沖池中已經修改的page,未及時flush到硬盤,但已經寫到redo log中。讀取和修改緩沖池的page很正常,可以提高效率,flush即可同步。臟數據是指事務對緩沖池中的行記錄record進行了修改,但是還沒提交!!!,如果這時讀取緩沖池中未提交的行數據就叫臟讀,違反了事務的隔離性。臟讀就是指當一個事務正在訪問數據,并且對數據進行了修改,而這種修改還沒有提交到數據庫中,這時,另外一個事務也訪問這個數據,然后使用了這個數據。
2)不重復讀 :解決了臟讀后,會遇到,同一個事務執行過程中,另外一個事務提交了新數據,因此本事務先后兩次讀到的數據結果會不一致。
是指在一個事務內,多次讀同一數據。在這個事務還沒有結束時,另外一個事務也訪問該同一數據。那么,在第一個事務中的兩次讀數據之間,由于第二個事務的修改,第二個事務已經提交。那么第一個事務兩次讀到的的數據可能是不一樣的。這樣就發生了在一個事務內兩次讀到的數據是不一樣的,因此稱為是不可重復讀。例如,一個編輯人員兩次讀取同一文檔,但在兩次讀取之間,作者重寫了該文檔。當編輯人員第二次讀取文檔時,文檔已更改。原始讀取不可重復。如果只有在作者全部完成編寫后編輯人員才可以讀取文檔,則可以避免該問題
3)幻讀: 解決了不重復讀,保證了同一個事務里,查詢的結果都是事務開始時的狀態(一致性)。但是,如果另一個事務同時提交了新數據,本事務再更新時,就會“驚奇的”發現了這些新數據,貌似之前讀到的數據是“鬼影”一樣的幻覺。
是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的數據進行了修改,這種修改涉及到表中的全部數據行。同時,第二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那么,以后就會發生操作第一個事務的用戶發現表中還有沒有修改的數據行,就好象發生了幻覺一樣。例如,一個編輯人員更改作者提交的文檔,但當生產部門將其更改內容合并到該文檔的主復本時,發現作者已將未編輯的新材料添加到該文檔中。如果在編輯人員和生產部門完成對原始文檔的處理之前,任何人都不能將新材料添加到文檔中,則可以避免該問題。
由于項目應用Doctrine ORM,通過setLockMode(LockMode::PESSIMISTIC_READ對應共享鎖或者LockMode::PESSIMISTIC_WRITE對應排它鎖)在查詢中添加加鎖操作。
總結
以上是生活随笔為你收集整理的mysql k,mysql事务有关概念-怀念K.Dures的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 最小二乘多项式拟合程序matlab,最小
- 下一篇: mysql 数据趋势,2019年8月全球