MySQL事务的四种隔离级别,mysql中的不可重复读和幻读的区别,Repeatable read可重复读隔离级别下怎么不存在幻读问题?
1. 事務的隔離級別
1.1 read uncommited:讀未提交。一個事務讀到了另一個事務未提交的臟數據,稱之為臟讀。
1.2 read commited:讀已提交。解決了臟讀問題,但當前事務兩次的讀取內容由于另一個事務修改并提交而不一致,出現了不可重復讀。
1.3 repeatable read:可重復讀。解決了不可重復讀,也就是當前事務讀不到其它事務修改并提交的數據,從而不會出現不可重復讀問題。
1.4 serializable:串行化。解決了幻讀問題,也就是當前事務沒有結束,其它事務無法進行其它任何操作,串行化操作。
2. 各個隔離級別的功能驗證
2.1 首先,MySQL的默認隔離級別是可重復讀,如下。
2.2 讀未提交隔離級別下的操作。
雖然系統屬性可以作用于所有會話,但是每次系統屬性更改后并不能立即在當前會話中起作用,需要退出重新進入;所以為了不退出重新進入,我們進入每個會話,都對當前會話的自動提交和隔離級別進行修改,操作如下。
// 更改當前會話的隔離級別和自動提交 set @@tx_isolation='xxx'; set @@autocommit=0;// 屬性前有global是系統屬性值 set @@global.tx_isolation='xxx'; set @@global.autocommit=0;雖然說變量前不加global時,是會話屬性,但是我這邊修改失敗了。
總結:①所以修改系統或會話屬性時,添加對應global或session更好,省略有時會有問題。②每次測試完一個隔離級別后,盡可能退出重新進入,我這邊連續測試隔離級別時會有問題。
兩個事務進行相應操作,如下圖。
2.3?讀已提交隔離級別下的操作。
還是保證事務的自動提交處于關閉狀態,并且更改事務隔離級別為read-committed,如下圖;
兩個事務進行相應操作,如下圖。
read committed隔離級別解決了臟讀問題,但是出現了不可重復讀問題。
2.4 可重復讀隔離級別下的操作
還是保證事務的自動提交處于關閉狀態,并且更改事務隔離級別為repeatable-read,如下圖;
兩個事務進行相應操作,解決了不可重復讀問題,如下圖。
以下圖片,說明mysql的repeatable read隔離級別可以解決幻讀問題?
repeatable read隔離級別解決了不可重復讀的問題,同時不存在幻讀問題,這是為什么?網上的教程不都說該隔離級別存在幻讀問題嗎?
其實這里涉及到快照讀和當前讀內容,上面的普通查詢語句屬于快照讀。快照讀:在事務首次select數據時,生成快照數據,之后的讀操作都會使用該快照數據(包含了其它庫和其它表的數據),因此repeatable read隔離級別下可以有效地避免不可重復讀以及讀數據的幻讀問題,如果中途有增刪改等更新操作,仍然出現幻讀問題。快照讀只在read committed和repeatable read兩種隔離級別才有,read committed隔離級別下每次讀取數據都會更新快照數據,而Repeatable Read只在事務首次讀取數據生成快照數據,之后讀操作都使用第一次的快照。當前讀:也叫鎖定讀,有兩種方式:①select ... lock in share node;②select ... for update。這種查詢其實是對相應記錄加鎖,其它事務的當前讀以及增刪改等操作都會被阻塞,如下圖。
2.5 ①快照讀在首次讀取數據才有快照;②會對其它庫的表數據進行“快照”,不僅僅是當前操作數據。驗證如下圖。
2.6 當前讀不會出現幻讀問題,因為操作都被阻塞了,如下圖。
總結
以上是生活随笔為你收集整理的MySQL事务的四种隔离级别,mysql中的不可重复读和幻读的区别,Repeatable read可重复读隔离级别下怎么不存在幻读问题?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring核心部分之AOP,aspec
- 下一篇: MySQL通过存储过程使用循环结构循环创