當(dāng)前位置:
首頁 >
同一事务中未提交的写能读到吗_03、MySQL事务的隔离性分析
發(fā)布時(shí)間:2025/3/12
31
豆豆
生活随笔
收集整理的這篇文章主要介紹了
同一事务中未提交的写能读到吗_03、MySQL事务的隔离性分析
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
事務(wù)可以用來保證數(shù)據(jù)庫的完整性:要么都做,要么不做。在 MySQL 中,事務(wù)支持是在引擎層實(shí)現(xiàn)的。你現(xiàn)在知道,MySQL 是一個(gè)支持多引擎的系統(tǒng),但并不是所有的引擎都支持事務(wù)。比如 MySQL 原生的 MyISAM 引擎就不支持事務(wù),這也是 MyISAM 被 InnoDB 取代的重要原因之一。事務(wù)的特性(ACID)原子性,是指整個(gè)數(shù)據(jù)庫的每個(gè)事務(wù)都是不可分割的單位。只有事務(wù)中的所有 SQL 語句都執(zhí)行成功,才算整個(gè)事務(wù)成功,事務(wù)才會(huì)被提交。如果事務(wù)中任何一個(gè) SQL 語句執(zhí)行失敗,整個(gè)事務(wù)都應(yīng)該被回滾。 一致性,是指將數(shù)據(jù)庫從一種一致性狀態(tài)轉(zhuǎn)換為下一種一致性狀態(tài)。不允許數(shù)據(jù)庫中的數(shù)據(jù)出現(xiàn)新老數(shù)據(jù)都有的情況,要么都是老數(shù)據(jù),要么都是新數(shù)據(jù)。用更書面化的表達(dá)就是:數(shù)據(jù)的完整性約束沒有被破壞。 隔離性,是指一個(gè)事務(wù)的影響在該事務(wù)提交前對(duì)其他事務(wù)都不可見,它通過鎖機(jī)制來實(shí)現(xiàn)。 持久性,是指事務(wù)一旦被提交,其結(jié)果就是永久性的。即使發(fā)生宕機(jī)等故障,數(shù)據(jù)庫也能將數(shù)據(jù)恢復(fù)。 事務(wù)的語法
--查看當(dāng)前隔離級(jí)別SHOW?VARIABLES?LIKE?'%transaction_isolation%';+-----------------------+------------------+| Variable_name | Value |+-----------------------+------------------+| transaction_isolation | REPEATABLE-READ |+-----------------------+------------------+-- 設(shè)定全局的隔離級(jí)別 設(shè)定會(huì)話 global 替換為 session 即可 把set語法溫習(xí)一下-- SET [GLOABL] config_name = 'foobar';-- SET @@[session|global].config_name = 'foobar';-- SELECT @@[global.]config_name;--全局修改SET @@gloabl.transaction_isolation = 0;SET @@gloabl.transaction_isolation = 'READ-UNCOMMITTED';SET @@gloabl.transaction_isolation = 1;SET @@gloabl.transaction_isolation = 'READ-COMMITTED';SET @@gloabl.transaction_isolation = 2;SET @@gloabl.transaction_isolation = 'REPEATABLE-READ';SET @@gloabl.transaction_isolation = 3;SET @@gloabl.transaction_isolation = 'SERIALIZABLE';--局部修改SET @@session.transaction_isolation = 0;SET @@session.transaction_isolation = 'READ-UNCOMMITTED';SET @@session.transaction_isolation = 1;SET @@session.transaction_isolation = 'READ-COMMITTED';SET @@session.transaction_isolation = 2;SET @@session.transaction_isolation = 'REPEATABLE-READ';SET @@session.transaction_isolation = 3;SET @@session.transaction_isolation = 'SERIALIZABLE';實(shí)例分析假設(shè)數(shù)據(jù)表 T 中只有一列,其中一行的值為 1,下面是按照時(shí)間順序執(zhí)行兩個(gè)事務(wù)的行為。
- 在 MySQL 命令行的默認(rèn)設(shè)置下,事務(wù)是自動(dòng)提交的,即執(zhí)行了SQL 語句之后會(huì)馬上執(zhí)行 commit 操作,我們可以設(shè)置 set autocommit=0 來禁用當(dāng)前回話的自動(dòng)提交。
- 還可以用 begin 、start transaction 來顯式的開始一個(gè)事務(wù)。
- commit 在默認(rèn)設(shè)置下是等價(jià)于 commit work 的,表示提交事務(wù)。
- rollback 在默認(rèn)設(shè)置下等價(jià)于 rollback work,表示事務(wù)回滾。
- savepoint xxx 表示定義一個(gè)保存點(diǎn),在一個(gè)事務(wù)中可以有多個(gè)保存點(diǎn)。
- release savepoint xxx 表示刪除一個(gè)保存點(diǎn),當(dāng)沒有該保存點(diǎn)的時(shí)候執(zhí)行該語句,會(huì)拋出一個(gè)異常。
- rollback to [savepoint] xxx 表示回滾到某個(gè)保存點(diǎn)。
- 臟讀 :一個(gè)事務(wù)開始讀取了某行數(shù)據(jù),另外一個(gè)事務(wù)已經(jīng)更新了此數(shù)據(jù)但沒有能夠及時(shí)提交。這是相當(dāng)危險(xiǎn)的,因?yàn)楹芸赡芩械牟僮鞫急换貪L。
- 不可重復(fù)讀:一個(gè)事務(wù)對(duì)同一行數(shù)據(jù)重復(fù)讀取兩次,但是卻得到了不同的結(jié)果。例如,在兩次讀取的中途,有另外一個(gè)事務(wù)對(duì)該型數(shù)據(jù)進(jìn)行了修改,并提交。
- 幻讀:事務(wù)在操作過程中進(jìn)行兩次查詢,第二次查詢的結(jié)果包含了第一次查詢中未出現(xiàn)的數(shù)據(jù)(MySQL8已解決該問題)。
讀未提交(?Read Uncommitted):
READ-UNCOMMITTED | 0:
存在臟讀,不可重復(fù)讀,幻讀的問題。
如果一個(gè)事務(wù)已經(jīng)開始寫數(shù)據(jù),則另外一個(gè)數(shù)據(jù)則不會(huì)允許同時(shí)進(jìn)行寫操作,但允許其他事務(wù)讀此行數(shù)據(jù)。
隔離級(jí)別可以通過“排他寫鎖”實(shí)現(xiàn)。
- 讀已提交(?Read committed):READ-COMMITTED | 1:解決臟讀的問題,存在不可重復(fù)讀,幻讀的問題。這個(gè)可以通過“排他寫鎖”實(shí)現(xiàn)。讀取數(shù)據(jù)的事務(wù)允許其他事務(wù)繼續(xù)訪問該行數(shù)據(jù),但是未提交的寫事務(wù)將會(huì)禁止其他事務(wù)訪問該行。
- 可重復(fù)讀取(Repeatable Read):REPEATABLE-READ | 2:解決臟讀,不可重復(fù)讀的問題,存在幻讀的問題,默認(rèn)隔離級(jí)別。可通過“共享鎖”,“排他鎖”實(shí)現(xiàn)。讀取數(shù)據(jù)的事務(wù)將會(huì)禁止寫事務(wù)(但允許讀事務(wù)),寫事務(wù)則禁止任何其他事務(wù)。
- 序列化(Serializable):SERIALIZABLE | 3:解決臟讀,不可重復(fù)讀,幻讀,可保證事務(wù)安全,但完全串行執(zhí)行,性能最低。提供嚴(yán)格的事務(wù)隔離。它要求事務(wù)序列化執(zhí)行,事務(wù)只能一個(gè)接著一個(gè)地執(zhí)行,不能并發(fā)執(zhí)行。如果僅僅通過“行級(jí)鎖”是無法實(shí)現(xiàn)事務(wù)序列化的,必須要通過其他機(jī)制保證新插入的數(shù)據(jù)不會(huì)被剛執(zhí)行查詢操作的事務(wù)訪問到。
| 隔離級(jí)別 | 讀數(shù)據(jù)一致性 | 臟讀 | 不可重復(fù)讀 | 幻讀 |
| 讀未提交? Read Uncommitted | 最低級(jí)別,只能保證不讀取物理上損壞的數(shù)據(jù) | 是 | 是 | 是 |
| 讀已提交? Read committed | 語句級(jí) | 否 | 是 | 是 |
| 可重復(fù)讀取 Repeatable Read | 事務(wù)隔離級(jí)別 | 否 | 否 | 是 |
| 序列化 Serializable | 最高級(jí)別,事務(wù)級(jí) | 否 | 否 | 否 |
- 若隔離級(jí)別是“讀未提交”, 則 V1 的值就是 2。這時(shí)候事務(wù) B 雖然還沒有提交,但是結(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。
Innodb的一條事務(wù)日志共經(jīng)歷4個(gè)階段:
- 創(chuàng)建階段:事務(wù)創(chuàng)建一條日志;
- 日志刷盤:日志寫入到磁盤上的日志文件;(ib_logfile里面)
- 數(shù)據(jù)刷盤:日志對(duì)應(yīng)的臟頁數(shù)據(jù)寫入到磁盤上的數(shù)據(jù)文件;
- 寫CKP:日志被當(dāng)作Checkpoint寫入日志文件;(ib_data里面)
總結(jié)
以上是生活随笔為你收集整理的同一事务中未提交的写能读到吗_03、MySQL事务的隔离性分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 随机森林特征重要性计算_R语言随机森林模
- 下一篇: mysql数据库权威指南_MySQL_M