關(guān)于msyql事務(wù)隔離你要知道
什么是事務(wù)?
事務(wù)是數(shù)據(jù)庫(kù)管理系統(tǒng)執(zhí)行過(guò)程中的一個(gè)邏輯單位,由一個(gè)有限的數(shù)據(jù)庫(kù)操作序列構(gòu)成。數(shù)據(jù)庫(kù)事務(wù)通常包含了一個(gè)序列的對(duì)數(shù)據(jù)庫(kù)的讀/寫(xiě)操作。包含有以下兩個(gè)目的:
- 為數(shù)據(jù)庫(kù)操作序列提供了一個(gè)從失敗中恢復(fù)到正常狀態(tài)的方法,同時(shí)提供了數(shù)據(jù)庫(kù)即使在異常狀態(tài)下仍能保持一致性的方法。
- 當(dāng)多個(gè)應(yīng)用程序在并發(fā)訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)時(shí),可以在這些應(yīng)用程序之間提供一個(gè)隔離方法,以防止彼此的操作互相干擾。
隔離性與隔離級(jí)別
提到事務(wù),你肯定會(huì)想到ACID(Atomicity、Consistency、Isolation、Durability,即原子性、一致性、隔離性、持久性),今 天我們就來(lái)說(shuō)說(shuō)其中I,也就是“隔離性”。當(dāng)數(shù)據(jù)庫(kù)上有多個(gè)事務(wù)同時(shí)執(zhí)行的時(shí)候,就可能出現(xiàn)臟讀(dirty read)、不可重復(fù)讀(non-repeatable read)、幻讀 (phantom read)的問(wèn)題,為了解決這些問(wèn)題,就有了“隔離級(jí)別”的概念。隔離級(jí)別做的越強(qiáng)則性能就越不好,所以要在性能與隔離級(jí)別中取一個(gè)平衡點(diǎn)。SQL標(biāo)準(zhǔn)的事務(wù)隔離級(jí)別包括:
- 讀未提交(read uncommitted):一個(gè)事務(wù)提交之后,它做的變更才會(huì)被其他事務(wù)看到。會(huì)產(chǎn)生臟讀。
- 讀已提交(read committed):一個(gè)事務(wù)提交之后,它做的變更才會(huì)被其他事務(wù)看到。會(huì)產(chǎn)生不可重復(fù)讀。
- 可重復(fù)讀(repeatable read) :一個(gè)事務(wù)執(zhí)行過(guò)程中看到的數(shù)據(jù),總是跟這個(gè)事務(wù)在啟動(dòng)時(shí)看到的數(shù)據(jù)是一致的。當(dāng)然在可重復(fù)讀隔離級(jí) 別下,未提交變更對(duì)其他事務(wù)也是不可⻅的。會(huì)產(chǎn)生幻讀。
- 串行化(serializable ):顧名思義是對(duì)于同一行記錄,“寫(xiě)”會(huì)加“寫(xiě)鎖”,“讀”會(huì)加“讀鎖”。當(dāng)出現(xiàn)讀寫(xiě)鎖沖突的時(shí)候,后訪(fǎng)問(wèn)的事務(wù)必須等前 一個(gè)事務(wù)執(zhí)行完成,才能繼續(xù)執(zhí)行。
| 隔離級(jí)別 | 臟讀 | 不可重復(fù)讀 | 幻讀 |
| 讀未提交 | 可以出現(xiàn) | 可以出現(xiàn) | 可以出現(xiàn) |
| 讀提交 | 不允許出現(xiàn) | 可以出現(xiàn) | 可以出現(xiàn) |
| 可重復(fù)讀 | 不允許出現(xiàn) | 不允許出現(xiàn) | 可以出現(xiàn) |
| 序列化 | 不允許出現(xiàn) | 不允許出現(xiàn) | 不允許出現(xiàn) |
主要是讀已提交和可重復(fù)讀比較難區(qū)分,所以我們看個(gè)小例子。先創(chuàng)建一張表,并插入數(shù)據(jù)1
create database test; use test; create table test(id int primary key); insert into test(id) values(1);
| 事務(wù)A | 事務(wù)B |
| 啟動(dòng)事務(wù)查詢(xún)得到1 | 啟動(dòng)事務(wù) |
| 查詢(xún)得到1 | |
| 將1改為2 | |
| 查詢(xún)得到V1 | |
| 提交事務(wù)B | |
| 查詢(xún)得到V2 | |
| 提交事務(wù)A | |
| 查詢(xún)得到V3 |
我們來(lái)看看在不同的隔離級(jí)別下,事務(wù)A會(huì)有哪些不同的返回結(jié)果,也就是圖里面V1、V2、V3的返回值分別是什么。
- 若隔離級(jí)別是“讀未提交”, 則V1的值就是2。這時(shí)候事務(wù)B雖然還沒(méi)有提交,但是結(jié)果已經(jīng)被A看到了。因此,V2、V3也都 是2。
- 若隔離級(jí)別是“讀提交”,則V1是1,V2的值是2。事務(wù)B的更新在提交后才能被A看到。所以, V3的值也是2。
- 若隔離級(jí)別是“可重復(fù)讀”,則V1、V2是1,V3是2。之所以V2還是1,遵循的就是這個(gè)要求:事務(wù)在執(zhí)行期間看到的數(shù)據(jù)前 后必須是一致的。
- 若隔離級(jí)別是“串行化”,則在事務(wù)B執(zhí)行“將1改成2”的時(shí)候,會(huì)被鎖住。直到事務(wù)A提交后,事務(wù)B才可以繼續(xù)執(zhí)行。所以從 A的⻆度看, V1、V2值是1,V3的值是2。
數(shù)據(jù)庫(kù)里面會(huì)創(chuàng)建一個(gè)視圖,訪(fǎng)問(wèn)的時(shí)候以視圖的邏輯結(jié)果為準(zhǔn)。在“可重復(fù)讀”隔離級(jí)別下,這個(gè)視圖是在事務(wù)啟 動(dòng)時(shí)創(chuàng)建的,整個(gè)事務(wù)存在期間都用這個(gè)視圖。在“讀提交”隔離級(jí)別下,這個(gè)視圖是在每個(gè)SQL語(yǔ)句開(kāi)始執(zhí)行的時(shí)候創(chuàng)建的。 這里需要注意的是,“讀未提交”隔離級(jí)別下直接返回記錄上的最新值,沒(méi)有視圖概念;而“串行化”隔離級(jí)別下直接用加鎖的方式來(lái)避免并行訪(fǎng)問(wèn)。
那什么時(shí)候需 要**“可重復(fù)讀”**的場(chǎng)景呢?
假設(shè)你在管理一個(gè)個(gè)人銀行賬戶(hù)表。一個(gè)表存了每個(gè)月月底的余額,一個(gè)表存了賬單明細(xì)。這時(shí)候你要做數(shù)據(jù)校對(duì),也就是判斷上個(gè)月的余額和當(dāng)前余額的差額,是否與本月的賬單明細(xì)一致。你一定希望在校對(duì)過(guò)程中,即使有用戶(hù)發(fā)生了一筆新的交 易,也不影響你的校對(duì)結(jié)果。
事務(wù)隔離的實(shí)現(xiàn)
在MySQL中,實(shí)際上每條記錄在更新的時(shí)候都會(huì)同時(shí)記錄一條回滾操作。記錄上的最新值,通過(guò)回滾操作,都可以得到前一個(gè)狀態(tài)的值。假設(shè)一個(gè)值從1被按順序改成了2、3、4,在回滾日志里面就會(huì)有類(lèi)似下面的記錄。

當(dāng)前值是4,但是在查詢(xún)這條記錄的時(shí)候,不同時(shí)刻啟動(dòng)的事務(wù)會(huì)有不同的read-view。如圖中看到的,在視圖A、B、C里面, 這一個(gè)記錄的值分別是1、2、4,同一條記錄在系統(tǒng)中可以存在多個(gè)版本,就是數(shù)據(jù)庫(kù)的多版本并發(fā)控制(MVCC)。對(duì)于 read-view A,要得到1,就必須將當(dāng)前值依次執(zhí)行圖中所有的回滾操作得到。即使現(xiàn)在有另外一個(gè)事務(wù)正在將4改成5,這個(gè)事務(wù)跟read-view A、B、C對(duì)應(yīng)的事務(wù)是不會(huì)沖突的。
回滾日志總不能一直保留吧,什么時(shí)候刪除呢?
在不需要的時(shí)候才刪除。也就是說(shuō),系統(tǒng)會(huì)判斷,當(dāng)沒(méi)有事務(wù)再需要用到這些回滾日志時(shí),回滾日志會(huì)被刪除。
什么時(shí)候才不需要了呢?
就是當(dāng)系統(tǒng)里沒(méi)有比這個(gè)回滾日志更早的read-view的時(shí)候。
為什么盡量不要使用事務(wù)?
事務(wù)意味著系統(tǒng)里面會(huì)存在很老的事務(wù)視圖,在這個(gè)事務(wù)提交之前,回滾記錄都要保留, 這會(huì)導(dǎo)致大量占用存儲(chǔ)空間。除此之外,事務(wù)還占用鎖資源,可能會(huì)拖垮庫(kù)。
以上就是關(guān)于msyql事務(wù)隔離你要知道的詳細(xì)內(nèi)容,更多關(guān)于mysql事務(wù)隔離的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Mysql事務(wù)隔離級(jí)別之讀提交詳解
- 通過(guò)實(shí)例分析MySQL中的四種事務(wù)隔離級(jí)別
- MySQL四種事務(wù)隔離級(jí)別詳解
- MySQL數(shù)據(jù)庫(kù)事務(wù)隔離級(jí)別詳解
- MySQL 四種事務(wù)隔離級(jí)別詳解及對(duì)比
- 深入解析MySQL的事務(wù)隔離及其對(duì)性能產(chǎn)生的影響
- MySQL中Innodb的事務(wù)隔離級(jí)別和鎖的關(guān)系的講解教程
- MySQL數(shù)據(jù)庫(kù)事務(wù)隔離級(jí)別介紹(Transaction Isolation Level)
相關(guān)文章
Mysql數(shù)據(jù)庫(kù)鎖定機(jī)制詳細(xì)介紹
這篇文章主要介紹了Mysql數(shù)據(jù)庫(kù)鎖定機(jī)制詳細(xì)介紹,本文用大量?jī)?nèi)容講解了Mysql中的鎖定機(jī)制,例如MySQL鎖定機(jī)制簡(jiǎn)介、合理利用鎖機(jī)制優(yōu)化MySQL等內(nèi)容,需要的朋友可以參考下2014-12-12
MySQL數(shù)據(jù)庫(kù)常見(jiàn)字段類(lèi)型長(zhǎng)度匯總大全
這篇文章主要給大家介紹了關(guān)于MySQL數(shù)據(jù)庫(kù)常見(jiàn)字段類(lèi)型長(zhǎng)度匯總大全的相關(guān)資料,需要的朋友可以參考下2024-05-05
MySQL select查詢(xún)之LIKE與通配符用法
這篇文章主要介紹了MySQL select查詢(xún)之LIKE與通配符用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
MySQL 百萬(wàn)級(jí)分頁(yè)優(yōu)化(Mysql千萬(wàn)級(jí)快速分頁(yè))
MySql 性能到底能有多高?用了php半年多,真正如此深入的去思考這個(gè)問(wèn)題還是從前天開(kāi)始。有過(guò)痛苦有過(guò)絕望,到現(xiàn)在充滿(mǎn)信心2012-11-11
通過(guò)DML更新MySQL數(shù)據(jù)庫(kù)數(shù)據(jù)的示例代碼
這篇文章主要給大家介紹了如何通過(guò)DML更新MySQL數(shù)據(jù)庫(kù)的數(shù)據(jù),通過(guò)DML來(lái)對(duì)數(shù)據(jù)庫(kù)種地表的數(shù)據(jù)記錄進(jìn)行增刪改查操作,文中給大家了詳細(xì)的代碼示例供大家參考,具有一定的參考價(jià)值,需要的朋友可以參考下2024-01-01
對(duì)比分析MySQL語(yǔ)句中的IN 和Exists
mysql中in 是把外表和內(nèi)表作hash 連接,而exists是對(duì)外表作loop循環(huán),每次loop循環(huán)再對(duì)內(nèi)表進(jìn)行查詢(xún)。一直以來(lái)認(rèn)為exists比in效率高的說(shuō)法是不準(zhǔn)確的。2018-06-06
MySQL數(shù)據(jù)庫(kù)忽略大小寫(xiě)的配置方法
這篇文章主要給大家介紹了MySQL數(shù)據(jù)庫(kù)忽略大小寫(xiě)的配置方法,文中通過(guò)代碼示例給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-01-01
mysql處理海量數(shù)據(jù)時(shí)的一些優(yōu)化查詢(xún)速度方法
最近一段時(shí)間由于工作需要,開(kāi)始關(guān)注針對(duì)Mysql數(shù)據(jù)庫(kù)的select查詢(xún)語(yǔ)句的相關(guān)優(yōu)化方法,需要的朋友可以參考下2017-04-04
MySQL導(dǎo)出數(shù)據(jù)遇到secure-file-priv問(wèn)題的解決方法
這篇文章主要為大家詳細(xì)介紹了MySQL導(dǎo)出數(shù)據(jù)遇到secure-file-priv問(wèn)題的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10

