1. 程式人生 > >高性能mysql 事務筆記

高性能mysql 事務筆記

解決 筆記 posit 開啟事務 ble sso 修改 size rac

事務的四大特性原子性、一致性、隔離性、持久性,

事務隔離的四大隔離級別:

READ UNCOMMITTED(未提交讀),

在 read uncommitted級別,事務中的修改,及時沒有提交,對其他事務也都是可見的。事物可以讀取未提交的數據,這也被稱為臟讀,你想如果所有的未提交的數據事物它讀取了,性能上是不是會差,所以在實際應用場景中很少應用

READ COMMITTED(提交讀),

提交讀是大部分數據庫的默認隔離級別,mysql卻不是,因為它所執行的是 一個數據至未提交事務之前 事務是看不到它的,所有事務都是不相幹的沒有關聯,所有的修改對其他事務是不可見的,這個級別也被稱為不可重復讀,因為兩次執行同樣的查詢,可能會得到不一樣的結果。

REPEATABLE READ(可重復讀),

可重讀讀是mysql的默認事務隔離級別,可重讀讀不會產生臟讀的情況,它保證了,在一個事務中多次讀取同樣記錄的結果是一致的,可重復讀在innodb和xtradb 儲存引擎中通過多版本並發控制解決看了幻讀的問題

SERIALIZABLE(可串行化)

可串行化是最高的隔離級別,它通過強制事務串執行,避免了幻讀的問題,簡單來說,可串行化會在讀取的每一行數據上都加上鎖,所以可能導致大量的超時和鎖爭用的問題,實際應用場景中很少用到,只有在非常需要確保數據一致性而且可以接受沒有並發的情況下,才考慮該級別隔離

mysql可重復讀和幻讀實例

2017年04月29日 22:54:27 CWeeYii 閱讀數:12979 版權聲明:本文為博主原創文章,原博地址。 https://blog.csdn.net/CWeeYii/article/details/70991230

mysql的默認事務級別是:可重復讀
其中可重復讀是通過mvcc來實現的又叫快照讀,在事務中的讀操作通過對當前的數據庫中記錄一個版本,以後的讀操作只會讀取記錄的版本,因此相當於對數據庫的數據建立了一個快照數據,因此叫做快照讀,其不用對數據庫中的數據進行加鎖又叫做樂觀鎖。
同時RR事務級別的mysql通當前讀和gap鎖來解決幻讀,其本質是通過對數據庫周邊記錄進行加悲觀鎖(讀鎖(共享鎖)和互斥鎖(寫鎖))【gap鎖】來解決幻讀。

1.什麽是幻讀問題

RR事務隔離級別號稱可以解決幻讀的問題(通過當前讀加鎖來實現)
第一步建表並插入5條記錄:
技術分享圖片

接下來我們看下大部分mysql所說的幻讀現象:
事務1(開啟事務查詢發現沒有記錄6準備插入):
技術分享圖片
事務2(開啟事務,發現沒有記錄6插入,並提交事務):
技術分享圖片
事務1:查詢發現沒有記錄6,現在開始進行插入6:
技術分享圖片
沒有的記錄我要插入卻告訴已經存在,這就是通常說的幻讀。

2.gap鎖(當前讀)解決幻讀問題

mysql說對數據加鎖不管共享鎖還是互斥鎖就能解決幻讀的問題
開啟一個事務1(加上共享鎖解決幻讀的情況):
技術分享圖片
開啟事務2(查詢發現沒有記錄8,準備插入)
技術分享圖片
可以發現事務2被阻塞,不準插入,除非事務1提交。因此在事務1中插入記錄8是能夠成功的。
事務1插入記錄8,最後可以查詢出自己插入的數據,但是更新一條不存在的數據是不會查詢出來的,最後提交事務:
技術分享圖片
事務2阻塞的操作會爆重復異常:
技術分享圖片
因此對一個事務加上悲觀鎖(共享鎖或者互斥鎖)是能夠保證幻讀不會出現的,並且誰先加鎖,誰就能夠保證check and insert是成功的。如果你需要每個事務的check and insert都能成功,那麽你不要加共享鎖,直接加互斥鎖。那麽事務會直接阻塞在加鎖階段,就不會出現check and insert 失敗的情況。
事務1加上互斥鎖
技術分享圖片
事務2也想加互斥鎖,BOOM你只能失敗:
技術分享圖片

3.RR沒有解決的幻讀

場景:我們知道grap鎖能夠將右邊的記錄進行加鎖,因此我要統計表記錄的數量,我只需要對最大記錄加鎖就行了
事務1:對最大記錄互斥加鎖,準備計算表中記錄數量。發現數量為8,並且不存在3和4的記錄。
技術分享圖片
事務2:插入缺失記錄3和4成功,但是插入id為100的記錄被鎖住,OK事務2可以提交了。
技術分享圖片
事務1:在事務1在事務2插入數據後進行查詢總量,發現數量還是6,OK很完美
技術分享圖片
事務1:接下來我發現事務1中沒有3和4這條記錄,我進行一次無用的更新會發生什麽?
技術分享圖片
OK,最終問題終於出現了,為什麽我更新兩條不存在的記錄,我能夠更新成功,並且我再次統計的時候,數量添加了兩條?並且我重新讀取,發現結果不一樣了,不是說可以重復讀嗎?加鎖可以解決幻讀嗎?
PS:如果一個事務裏面插入或者刪除會改變記錄的數據,這個是合理的不是幻讀。更新應該只會修改數據記錄,這個也是合理,同樣不是幻讀,都是可重復讀的。但是更新出現新的記錄就是一種異常的情況。

高性能mysql 事務筆記