關于msyql事務隔離你要知道
什么是事務?
事務是數(shù)據(jù)庫管理系統(tǒng)執(zhí)行過程中的一個邏輯單位,由一個有限的數(shù)據(jù)庫操作序列構成。數(shù)據(jù)庫事務通常包含了一個序列的對數(shù)據(jù)庫的讀/寫操作。包含有以下兩個目的:
- 為數(shù)據(jù)庫操作序列提供了一個從失敗中恢復到正常狀態(tài)的方法,同時提供了數(shù)據(jù)庫即使在異常狀態(tài)下仍能保持一致性的方法。
- 當多個應用程序在并發(fā)訪問數(shù)據(jù)庫時,可以在這些應用程序之間提供一個隔離方法,以防止彼此的操作互相干擾。
隔離性與隔離級別
提到事務,你肯定會想到ACID(Atomicity、Consistency、Isolation、Durability,即原子性、一致性、隔離性、持久性),今 天我們就來說說其中I,也就是“隔離性”。當數(shù)據(jù)庫上有多個事務同時執(zhí)行的時候,就可能出現(xiàn)臟讀(dirty read)、不可重復讀(non-repeatable read)、幻讀 (phantom read)的問題,為了解決這些問題,就有了“隔離級別”的概念。隔離級別做的越強則性能就越不好,所以要在性能與隔離級別中取一個平衡點。SQL標準的事務隔離級別包括:
- 讀未提交(read uncommitted):一個事務提交之后,它做的變更才會被其他事務看到。會產(chǎn)生臟讀。
- 讀已提交(read committed):一個事務提交之后,它做的變更才會被其他事務看到。會產(chǎn)生不可重復讀。
- 可重復讀(repeatable read) :一個事務執(zhí)行過程中看到的數(shù)據(jù),總是跟這個事務在啟動時看到的數(shù)據(jù)是一致的。當然在可重復讀隔離級 別下,未提交變更對其他事務也是不可⻅的。會產(chǎn)生幻讀。
- 串行化(serializable ):顧名思義是對于同一行記錄,“寫”會加“寫鎖”,“讀”會加“讀鎖”。當出現(xiàn)讀寫鎖沖突的時候,后訪問的事務必須等前 一個事務執(zhí)行完成,才能繼續(xù)執(zhí)行。
隔離級別 | 臟讀 | 不可重復讀 | 幻讀 |
讀未提交 | 可以出現(xiàn) | 可以出現(xiàn) | 可以出現(xiàn) |
讀提交 | 不允許出現(xiàn) | 可以出現(xiàn) | 可以出現(xiàn) |
可重復讀 | 不允許出現(xiàn) | 不允許出現(xiàn) | 可以出現(xiàn) |
序列化 | 不允許出現(xiàn) | 不允許出現(xiàn) | 不允許出現(xiàn) |
主要是讀已提交和可重復讀比較難區(qū)分,所以我們看個小例子。先創(chuàng)建一張表,并插入數(shù)據(jù)1
create database test; use test; create table test(id int primary key); insert into test(id) values(1);
事務A | 事務B |
啟動事務查詢得到1 | 啟動事務 |
查詢得到1 | |
將1改為2 | |
查詢得到V1 | |
提交事務B | |
查詢得到V2 | |
提交事務A | |
查詢得到V3 |
我們來看看在不同的隔離級別下,事務A會有哪些不同的返回結果,也就是圖里面V1、V2、V3的返回值分別是什么。
- 若隔離級別是“讀未提交”, 則V1的值就是2。這時候事務B雖然還沒有提交,但是結果已經(jīng)被A看到了。因此,V2、V3也都 是2。
- 若隔離級別是“讀提交”,則V1是1,V2的值是2。事務B的更新在提交后才能被A看到。所以, V3的值也是2。
- 若隔離級別是“可重復讀”,則V1、V2是1,V3是2。之所以V2還是1,遵循的就是這個要求:事務在執(zhí)行期間看到的數(shù)據(jù)前 后必須是一致的。
- 若隔離級別是“串行化”,則在事務B執(zhí)行“將1改成2”的時候,會被鎖住。直到事務A提交后,事務B才可以繼續(xù)執(zhí)行。所以從 A的⻆度看, V1、V2值是1,V3的值是2。
數(shù)據(jù)庫里面會創(chuàng)建一個視圖,訪問的時候以視圖的邏輯結果為準。在“可重復讀”隔離級別下,這個視圖是在事務啟 動時創(chuàng)建的,整個事務存在期間都用這個視圖。在“讀提交”隔離級別下,這個視圖是在每個SQL語句開始執(zhí)行的時候創(chuàng)建的。 這里需要注意的是,“讀未提交”隔離級別下直接返回記錄上的最新值,沒有視圖概念;而“串行化”隔離級別下直接用加鎖的方式來避免并行訪問。
那什么時候需 要**“可重復讀”**的場景呢?
假設你在管理一個個人銀行賬戶表。一個表存了每個月月底的余額,一個表存了賬單明細。這時候你要做數(shù)據(jù)校對,也就是判斷上個月的余額和當前余額的差額,是否與本月的賬單明細一致。你一定希望在校對過程中,即使有用戶發(fā)生了一筆新的交 易,也不影響你的校對結果。
事務隔離的實現(xiàn)
在MySQL中,實際上每條記錄在更新的時候都會同時記錄一條回滾操作。記錄上的最新值,通過回滾操作,都可以得到前一個狀態(tài)的值。假設一個值從1被按順序改成了2、3、4,在回滾日志里面就會有類似下面的記錄。
當前值是4,但是在查詢這條記錄的時候,不同時刻啟動的事務會有不同的read-view。如圖中看到的,在視圖A、B、C里面, 這一個記錄的值分別是1、2、4,同一條記錄在系統(tǒng)中可以存在多個版本,就是數(shù)據(jù)庫的多版本并發(fā)控制(MVCC)。對于 read-view A,要得到1,就必須將當前值依次執(zhí)行圖中所有的回滾操作得到。即使現(xiàn)在有另外一個事務正在將4改成5,這個事務跟read-view A、B、C對應的事務是不會沖突的。
回滾日志總不能一直保留吧,什么時候刪除呢?
在不需要的時候才刪除。也就是說,系統(tǒng)會判斷,當沒有事務再需要用到這些回滾日志時,回滾日志會被刪除。
什么時候才不需要了呢?
就是當系統(tǒng)里沒有比這個回滾日志更早的read-view的時候。
為什么盡量不要使用事務?
事務意味著系統(tǒng)里面會存在很老的事務視圖,在這個事務提交之前,回滾記錄都要保留, 這會導致大量占用存儲空間。除此之外,事務還占用鎖資源,可能會拖垮庫。
以上就是關于msyql事務隔離你要知道的詳細內容,更多關于mysql事務隔離的資料請關注腳本之家其它相關文章!
相關文章
MySQL 處理重復數(shù)據(jù)的方法(防止、刪除)
這篇文章主要介紹了MySQL 處理重復數(shù)據(jù)的方法,文中示例代碼非常詳細,幫助大家更好的理解和學習,感興趣的朋友可以了解下2020-07-07Django2.* + Mysql5.7開發(fā)環(huán)境整合教程圖解
這篇文章主要介紹了Django2.* + Mysql5.7開發(fā)環(huán)境整合教程,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-09-09MySQL8下忘記密碼后重置密碼的辦法(MySQL老方法不靈了)
這篇文章主要介紹了MySQL8下忘記密碼后重置密碼的辦法,MySQL的密碼是存放在user表里面的,修改密碼其實就是修改表中記錄,重置的思路是是想辦法不用密碼進入系統(tǒng),然后用數(shù)據(jù)庫命令修改表user中的密碼記錄2018-08-08MySQL 利用frm文件和ibd文件恢復表數(shù)據(jù)
這篇文章主要介紹了MySQL 利用frm文件和ibd文件恢復表數(shù)據(jù),幫助大家更好的理解和學習使用MySQL,感興趣的朋友可以了解下2021-03-03linux下多個mysql5.7.19(tar.gz)安裝圖文教程
這篇文章主要為大家詳細介紹了linux下多個mysql5.7.19tar.gz安裝教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07MySQL快速禁用賬戶登入及如何復制/復用賬戶密碼(最新推薦)
這篇文章主要介紹了MySQL如何快速禁用賬戶登入及如何復制/復用賬戶密碼,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2024-01-01