国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

MySQL事務(wù)(4種事務(wù)隔離級別、臟寫、臟讀、不可重復(fù)讀、幻讀、當(dāng)前讀、快照讀、MVCC、事務(wù)指標(biāo)監(jiān)控)

這篇具有很好參考價值的文章主要介紹了MySQL事務(wù)(4種事務(wù)隔離級別、臟寫、臟讀、不可重復(fù)讀、幻讀、當(dāng)前讀、快照讀、MVCC、事務(wù)指標(biāo)監(jiān)控)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

聲明測試表,供文章案例使用

CREATE TABLE `cs` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `num` int(10) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

事務(wù)的分類

  • 顯示事務(wù):
    • read write:讀寫事務(wù),默認模式,表示當(dāng)前事務(wù)可以讀寫數(shù)據(jù)。
    • read only:只讀事務(wù),很少用,表示當(dāng)前事務(wù)不能修改數(shù)據(jù)。
    • with consistent snapshot:一致性快照,在數(shù)據(jù)庫事務(wù)中確保事務(wù)在執(zhí)行過程中能看到一個事務(wù)開始時的一致數(shù)據(jù)庫狀態(tài),避免被其他并發(fā)操作影響。
  • 隱式事務(wù):不需要顯示聲明事務(wù)相關(guān)語句,autocommit是開啟狀態(tài)(默認值),每條DML和DDL的SQL語句都是一個獨立的事務(wù)。

MySQL事務(wù)的4個特性:

  • 原子性(Atomicity):當(dāng)前事務(wù)中的執(zhí)行結(jié)果,要么全部執(zhí)行成功,要么全部執(zhí)行失敗。
  • 一致性(Consistency):事務(wù)執(zhí)行前后,數(shù)據(jù)庫從一個合法(指符合業(yè)務(wù)預(yù)期)狀態(tài)轉(zhuǎn)換成另一個一合法狀態(tài)。
  • 隔離性(Isolation):多個事務(wù)可以并發(fā)執(zhí)行,各個事務(wù)之間的操作互相隔離互不干擾。
  • 持久性(Durability):無論事務(wù)提交還是回滾,都會持久化到磁盤中。

自動提交

自動提交(auto commit),指的是SQL語句執(zhí)行完畢后自動將數(shù)據(jù)持久化到磁盤(刷盤)中。
顯式的聲明事務(wù),或者聲明set autocommit = 0;都可以關(guān)閉自動提交。

savepoint

  • 俗稱保存點,是用于實現(xiàn)部分事務(wù)回滾的一種機制,需要確定從哪里開始回滾,就需要savepoint的標(biāo)識來定位。
  • 回滾范圍:從保存點開始到事務(wù)最后一條SQL,都會被回滾。
  • 適用場景:用于復(fù)雜的業(yè)務(wù)邏輯中,給出靈活可控的后悔藥,降低事務(wù)回滾影響范圍。
  • 注意:rollback to之后,不代表事務(wù)流程走完,還需要再次commit提交其它未回滾的事務(wù)。
  • 用法:
    savepoint 保存點名:創(chuàng)建一個 Savepoint,并為其指定一個名稱。
    rollbackto savepoint 保存點名;:將事務(wù)回滾到指定的 Savepoint。
    release savepoint 保存點名;:釋放指定的 Savepoint。
    示例:
start transaction;
insert into cs(num) values(1);
savepoint insert_1;
insert into cs(num) values(2);
savepoint insert_2;
insert into cs(num) values(3);
savepoint insert_3;
insert into cs(num) values(4);
savepoint insert_4;
rollback to insert_2;
commit;
發(fā)現(xiàn)1,2數(shù)據(jù)被插入。

事務(wù)的隱式提交

在上一個事務(wù)沒提交或回滾時,運行下一個事務(wù),則上一個事務(wù)自動提交。

start transaction;
insert into cs(num) values(1);
insert into cs(num) values(2);
start transaction;
insert into cs(num) values(3);
insert into cs(num) values(4);
commit;
成功插入1,2,3,4。

4種隔離級別

  • 讀未提交(Read Uncommitted):最低級別的隔離,事務(wù)中的修改即使未提交也能被其他事務(wù)看到,可能導(dǎo)致臟讀、不可重復(fù)讀和幻讀問題。
  • 讀已提交(Read Committed):保證一個事務(wù)提交后對其他事務(wù)可見,避免了臟讀,但可能會導(dǎo)致不可重復(fù)讀和幻讀問題。
  • 可重復(fù)讀(Repeatable Read):保證在同一事務(wù)內(nèi)多次讀取數(shù)據(jù)時,數(shù)據(jù)保持一致,避免了不可重復(fù)讀問題,但仍可能出現(xiàn)幻讀。
  • 串行化(Serializable):最高級別的隔離,通過對讀取的數(shù)據(jù)添加共享鎖或排他鎖來確保事務(wù)之間的隔離性,避免了臟讀、不可重復(fù)讀和幻讀問題,但可能會影響并發(fā)性能。

表格從上到下,越來越高可用,但是性能越來越低。

隔離級別 是否解決臟讀 是否解決不可重復(fù)讀 是否解決幻讀 是否加鎖
讀未提交
讀已提交
可重復(fù)讀
串行化

查看或設(shè)置MySQL隔離級別

  • 查看:select @@transaction_isolation; 或者 show variables like 'transaction_isolation;'
  • 設(shè)置:set session transaction_isolation = 'read-uncommitted/read-committed/repeatable-read/serializable';
    注意隔離級別是回話級別的,所以無法set glboal。

MySQL會發(fā)生什么讀?

因為mysql默認隔離級別是可重復(fù)讀(Repeatable Read),所以只會發(fā)生幻讀情況,臟讀和可重復(fù)度不會發(fā)生,除非改事務(wù)隔離級別。

臟寫(不允許發(fā)生)

  • 簡介:一個事務(wù)修改某些數(shù)據(jù)時,另一個事務(wù)在未提交的情況下也修改了這些數(shù)據(jù),引起的導(dǎo)致數(shù)據(jù)的不一致性。
  • 危害:造成數(shù)據(jù)在并發(fā)情況下嚴(yán)重不一致。
  • 演示:試不出來,臟寫這么嚴(yán)重的bug,是不允許發(fā)生的情況。

臟讀(讀未提交隔離級別會發(fā)生)

  • 簡介:一個事務(wù)尚未commit(提交,刷盤,持久化),卻讀取了事務(wù)修改后的值,引起數(shù)據(jù)讀取不準(zhǔn)確的情況。
  • 危害:事務(wù)還未提交就被讀取了,該事務(wù)成功提交還好,要是回滾了,會造成讀取數(shù)據(jù)不一致的問題。
  • 演示:因為臟讀是讀未提交(Read Uncommitted)才會發(fā)生的情況,所以要降低MySQL的隔離級別。
步驟 會話A 會話B 備注
1 set session transaction_isolation = 'read-committed'; set session transaction_isolation = 'read-committed'; 設(shè)置事務(wù)的隔離級別為讀未提交
2 select @@transaction_isolation; select @@transaction_isolation; 檢查隔離級別是否設(shè)置成功
3 select num from cs where id = 20; #20 start transaction;
update cs set num = 20 where id = 40;
會話A num的初始值為20
4 select num from cs where id = 20; #40 / 會話B并未commit,此時會話A中num的值為40,發(fā)生臟讀現(xiàn)象
5 / rollback 結(jié)束本次事務(wù)
6 select num from cs where id = 20; #20 / num恢復(fù)為20

不可重復(fù)讀(讀未提交、讀已提交隔離級別會發(fā)生)

  • 簡介:在事務(wù)A中讀取某些數(shù)據(jù),然后在事務(wù)B中修改這些數(shù)據(jù),此時事務(wù)A讀取這些數(shù)據(jù)還未發(fā)生變化,但是事務(wù)B提交后,并在事務(wù)A在未結(jié)束事務(wù)的前提下,那些數(shù)據(jù)發(fā)生了變化,不可重復(fù)讀不是禁止讀動作,而是重復(fù)讀數(shù)據(jù)不一致。
    一句話概括,在同一個事務(wù)中,受其它事務(wù)提交的影響,讀取同一數(shù)據(jù)兩次得到的結(jié)果不一致的現(xiàn)象。
  • 危害:破壞了事務(wù)內(nèi)數(shù)據(jù)的準(zhǔn)確性,例如事務(wù)內(nèi)的SQL有自增自減的邏輯,如果事務(wù)內(nèi)的初始值受其他事物提交從而發(fā)生變化,那么這是個巨大的問題。
  • 演示:因為不可重復(fù)讀是讀已提交(Read Committed)才會發(fā)生的情況,所以要降低MySQL的隔離級別。
步驟 會話A 會話B 備注
1 set session transaction_isolation = 'read-uncommitted'; set session transaction_isolation = 'read-uncommitted'; 設(shè)置事務(wù)隔離級別為讀已經(jīng)提交
2 select @@transaction_isolation; select @@transaction_isolation; 檢查隔離級別是否設(shè)置成功
3 start transaction; start transaction; 雙方開啟事務(wù)
4 select num from cs where id = 20; #20 select num from cs where id = 20; #20 兩個會話中num的值為20
5 update cs set num = 40 where id = 20; select num from cs where id = 20; #20 會話A將數(shù)據(jù)更新為40,此時會話B查詢的值仍為20
6 commit select num from cs where id = 40; #40 會話A提交事務(wù),會話B仍在事務(wù)中,但是得到的值變成了40,發(fā)生了不可重復(fù)讀
7 / commit 結(jié)束事務(wù)

幻讀(讀未提交、讀已提交、可重復(fù)讀隔離級別會發(fā)生)

  • 簡介:同一個事務(wù)里前后查詢兩次相同范圍的數(shù)據(jù),后一次查詢查詢到了前一次看不到的東西,就好像出現(xiàn)了"幻影"一樣。(注意,如果把會話B的insert改為delete導(dǎo)致的數(shù)據(jù)減少,不算幻讀,算不可重復(fù)讀)。
  • 危害:沒有充分的做好數(shù)據(jù)隔離,數(shù)據(jù)一致性存在問題。
  • 演示:mysql 的默認隔離級別為REPEATABLE-READ,所以大概率不用調(diào)整隔離級別。
步驟 會話A 會話B 備注
1 select @@transaction_isolation; select @@transaction_isolation; 檢查隔離級別是否是REPEATABLE-READ
2 start transaction; start transaction; 雙方開啟事務(wù)
3 select * from cs; select * from cs; 兩個事務(wù)查看,都只有id為20的一條數(shù)據(jù)
4 insert into cs (id,num) values(21,21); select * from cs; 會話B查詢,仍舊只有id為20的一條數(shù)據(jù)
5 commit / 會話A提交事務(wù)
6 / select * from cs; 即使會話A提交了事務(wù),會話B查詢?nèi)耘f無法搜索到會話A插入的數(shù)據(jù),起始這一步已經(jīng)幻讀了,但是mysql不表明是幻讀,所以到第7步測試
7 / insert into cs (id,num) values(21,21); 因為會話B select查不到id為21的數(shù)據(jù),所以插入id相同的數(shù)據(jù),但是報錯1062 - Duplicate entry '21' for key 'PRIMARY'
8 / rollback; 回滾以結(jié)束事務(wù)流程

如何解決幻讀?

  • 或者使用串行化的隔離級別。在串行化隔離級別下,也會隱式的添加行(X)鎖。
  • 添加間隙鎖,可以避免幻讀。
  • mysql 的默認隔離級別為REPEATABLE-READ,又稱為RR,通過MVCC的機制,如果對數(shù)據(jù)進行快照讀,正因為讀取的不一定第最新的數(shù)據(jù),所以可以防止幻讀(注意不是解決幻讀),如果是當(dāng)前讀(最近數(shù)據(jù)),那么仍舊會發(fā)生幻讀現(xiàn)象。

當(dāng)前讀

當(dāng)前讀讀的就是數(shù)據(jù)最新的記錄,需要保證當(dāng)前讀的數(shù)據(jù)不能被修改,修改了就不是最新的記錄了(臟寫),因此需要加鎖,select for update、select lock in share mode以及DML(insert、update、delete)獲取的數(shù)據(jù)都是當(dāng)前讀的數(shù)據(jù)。

快照讀

快照讀顧名思義,讀取的就是由MVCC Read View控制的undo log的數(shù)據(jù),不加鎖,所以是讀取是非阻塞的。不加鎖的select都屬于快照讀。如果當(dāng)前事務(wù)的隔離級別是串行化,那么快照讀也變成了當(dāng)前讀。
舉個例子:常用的navicat,查看一個表,事務(wù)提交前的insert或update語句,表格內(nèi)仍舊顯示的原數(shù)據(jù),則用的快照讀。

MVCC

MVCC(Multi-Version Concurrency Control)是 MySQL 中一種實現(xiàn)事務(wù)隔離的機制,用于處理數(shù)據(jù)庫事務(wù)并發(fā)訪問時可能出現(xiàn)的讀寫沖突。事務(wù)的四種隔離級別,就是通過MVCC機制提供的底層支撐。
MVCC三板斧:隱藏字段、Undo log(存放歷史版本)、Read view(版本控制)

MVCC解決的是讀已提交和可重復(fù)讀級別的并發(fā)控制。
因為讀未提交,就算事務(wù)未提交,可以直接讀取最新的數(shù)據(jù)(臟讀),相當(dāng)于當(dāng)前讀,那就不分快照讀和當(dāng)前讀了。
串行化的隔離級別,強制事務(wù)串行執(zhí)行,也不存在快照讀和當(dāng)前讀的區(qū)分,因為讀取的都是事務(wù)執(zhí)行過后的最新數(shù)據(jù)。

事務(wù)各項指標(biāo)監(jiān)控

查看 InnoDB 存儲引擎中當(dāng)前活動的事務(wù)信息。文章來源地址http://www.zghlxwxcb.cn/news/detail-838026.html

SELECT * FROM information_schema.innodb_trx;

trx_id                         事務(wù)的唯一標(biāo)識符。
trx_state                      事務(wù)的狀態(tài),如 RUNNING、LOCK WAIT、ROLLING BACK 等。
trx_started                    事務(wù)啟動的時間。
trx_requested_lock_id          請求的鎖的標(biāo)識符。
trx_wait_started               等待鎖的開始時間。
trx_weight                     事務(wù)的權(quán)重,用于死鎖檢測。
trx_mysql_thread_id            MySQL 線程 ID。
trx_query                      與事務(wù)相關(guān)的 SQL 查詢語句。
trx_operation_state            事務(wù)內(nèi)部操作的狀態(tài)。
trx_tables_in_use              事務(wù)使用的表的數(shù)量。
trx_tables_locked              事務(wù)鎖定的表的數(shù)量。
trx_lock_structs               事務(wù)內(nèi)部使用的鎖結(jié)構(gòu)數(shù)量。
trx_lock_memory_bytes          用于事務(wù)鎖定的內(nèi)存字節(jié)數(shù)。
trx_rows_locked                事務(wù)鎖定的行數(shù)。
trx_rows_modified              事務(wù)修改的行數(shù)。
trx_concurrency_tickets        用于事務(wù)并發(fā)控制的票數(shù)。
trx_isolation_level            事務(wù)的隔離級別。
trx_unique_checks              是否啟用了唯一性檢查。
trx_foreign_key_checks         是否啟用了外鍵約束檢查。
trx_last_foreign_key_error     最后一個外鍵錯誤信息。
trx_adaptive_hash_latched      是否適應(yīng)性哈希被鎖定。
trx_adaptive_hash_timeout      適應(yīng)性哈希鎖定超時次數(shù)。
trx_is_foreign_key_with_check  是否用于外鍵約束檢查。
trx_is_foreign_key             是否用于外鍵約束。

到了這里,關(guān)于MySQL事務(wù)(4種事務(wù)隔離級別、臟寫、臟讀、不可重復(fù)讀、幻讀、當(dāng)前讀、快照讀、MVCC、事務(wù)指標(biāo)監(jiān)控)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Mysql 索引 、事務(wù)、隔離級別

    Mysql 索引 、事務(wù)、隔離級別

    目錄 索引(index) 1.為什么要有索引? 2.引入索引的代價 3.索引的操作 4.索引的使用場景 5.索引的底層原理 事務(wù) (transaction) 事物的回滾是怎么做到的 事物的四大特性 并發(fā)執(zhí)行事務(wù)帶來的問題 隔離級別 索引是一種為了加快數(shù)據(jù)庫查詢(操作)速度而引入的一種手段,需要占用額

    2024年01月20日
    瀏覽(22)
  • 詳解MySQL事務(wù)隔離級別

    一個事務(wù)具有 ACID 特性,也就是(Atomicity、Consistency、Isolation、Durability,即 原子性 、 一致性 、 隔離性 、 持久性 ),本文主要講解一下其中的 Isolation ,也就是事務(wù)的 隔離性 。 概述 四種隔離級別分別是: 讀未提交(Read Uncommitted) :最低的隔離級別,事務(wù)對數(shù)據(jù)的修改即使

    2024年02月09日
    瀏覽(24)
  • 【MYSQL】事務(wù)隔離級別

    【MYSQL】事務(wù)隔離級別

    臟讀 一個事務(wù)正在對一條記錄做修改,在這個事務(wù)完成并提交前,另一個事務(wù)也來讀取同一條記錄,讀取了這些未提交的“臟”數(shù)據(jù),并據(jù)此做進一步的處理,就會產(chǎn)生未提交的數(shù)據(jù)依賴關(guān)系。這種現(xiàn)象被形象的叫作’臟讀’(Dirty Reads)。 例子:事務(wù)A修改了一條數(shù)據(jù)1狀態(tài)

    2024年01月19日
    瀏覽(49)
  • 【MySQL】事務(wù)與隔離級別詳解

    【MySQL】事務(wù)與隔離級別詳解

    事務(wù)就是一組DML語句組成 ,這些語句在邏輯上存在相關(guān)性,這一組DML語句要么全部成功,要么全部失敗,是一個整體(原子性)。例如買票操作,上層看來是一個單純的買票操作,但是下層卻需要一條或多條SQL語句來完成轉(zhuǎn)賬操作,這一組SQL是一個整體,被稱為事務(wù)。事務(wù)還

    2024年02月15日
    瀏覽(35)
  • MySQL的事務(wù)特性、事務(wù)特性保證和事務(wù)隔離級別

    ????????事務(wù)是指要么所有的操作都成功執(zhí)行,要么所有的操作都不執(zhí)行的一組數(shù)據(jù)庫操作。 一、MySQL提供了四個事務(wù)特性,即ACID: ??? ?????1. 原子性(Atomicity) :一個事務(wù)中的所有操作要么全部提交成功,要么全部回滾失敗,保證事務(wù)的原子性。 ??????? ?2. 一

    2024年02月03日
    瀏覽(22)
  • mysql不同隔離級別事務(wù)插入數(shù)據(jù)

    mysql不同隔離級別事務(wù)插入數(shù)據(jù)

    面試中問到了相關(guān)問題,做下問題記錄 問題是這樣的,數(shù)據(jù)庫默認隔離級別下,事務(wù)A插入一條數(shù)據(jù),沒有提交,事務(wù)B插入一條數(shù)據(jù),提交,表id為自增,如果表是空表,事務(wù)A和事務(wù)B的id分別是多少。 2.1.1 打開一個mysql窗口,事務(wù)A 執(zhí)行代碼塊 2.1.2 打開另一個窗口,事務(wù)B 執(zhí)

    2024年02月11日
    瀏覽(24)
  • 【MySql】MySql事務(wù)隔離級別與一致性

    【MySql】MySql事務(wù)隔離級別與一致性

    MySQL服務(wù)可能會同時被多個客戶端進程(線程)訪問,訪問的方式以事務(wù)方式進行 一個事務(wù)可能由多條SQL構(gòu)成,也就意味著,任何一個事務(wù),都有執(zhí)行前,執(zhí)行中,執(zhí)行后的階段。而所謂的原子性,其實就是讓用戶層,要么看到執(zhí)行前,要么看到執(zhí)行后。執(zhí)行中出現(xiàn)問題,可以

    2024年02月10日
    瀏覽(22)
  • MySQL - 并發(fā)控制與事務(wù)的隔離級別【頭歌】

    目錄 相關(guān)知識 并發(fā)操作可能產(chǎn)生的數(shù)據(jù)不一致性 MySQL的事務(wù)隔離級別 示例 第一關(guān):并發(fā)控制與事務(wù)的隔離級別 編程要求 測試說明 代碼如下 第二關(guān):讀臟 任務(wù)描述 相關(guān)知識 讀臟 讀臟產(chǎn)生的原因 編程要求 代碼如下: 第三關(guān):不可重復(fù)讀 任務(wù)描述 相關(guān)知識 不可重復(fù)讀

    2024年02月09日
    瀏覽(60)
  • 幻讀與不可重復(fù)讀的區(qū)分

    幻讀與不可重復(fù)讀的區(qū)分

    ????????幻讀重點在于數(shù)據(jù) 是否存在 。原本不存在的數(shù)據(jù)卻真實的存在了,這便是幻讀。 ????????在同一個事務(wù)中,第一次讀取到結(jié)果集和第二次讀取到的結(jié)果集不同。引起幻讀的原因在于另一個事務(wù)進行了 INSERT 操作。 ????????不可重復(fù)讀重點在于數(shù)據(jù) 是否被改

    2024年02月07日
    瀏覽(18)
  • MySQL5-事務(wù)隔離級別和鎖機制

    MySQL5-事務(wù)隔離級別和鎖機制

    ?? 個人主頁:程序員句號 ?? 支持水滴:點贊?? + 收藏? + 留言??+關(guān)注 ?? 訂閱專欄:MySQL性能調(diào)優(yōu) 原創(chuàng)博文、基礎(chǔ)知識點講解、有一定指導(dǎo)意義的中高級實踐文章。 認真或有趣的技術(shù)分享。 MySQL性能優(yōu)化專欄 1.MySQL性能優(yōu)化1-MySQL底層索引結(jié)構(gòu) 2.MySQL2-Explain詳解 3.MySQL

    2024年02月07日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包