日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql查看版本号_十分钟了解MySQL事务机制

發布時間:2024/9/27 数据库 56 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql查看版本号_十分钟了解MySQL事务机制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

讀書百遍其義自現。

MySQL數據庫在我們平時工作學習中的使用頻率是相當之高,徹底掌握MySQL的事務機制對我們平時工作會有非常大的幫助,仔細回憶一下,你是否對MySQL事務相關的知識是否完全掌握?是否感覺有的地方有些模糊?通過這篇文章讓你徹底理順邏輯,下面就開始吧!

01事務的特性

事務的特點

提到數據庫的事務,我們肯定脫口而出的就是ACID,但是有的時候并不清楚ACID到底是什么,掌握事務的特性對于我們接下來學習是相當重要的。

首先舉個例子,老王去銀行轉賬的例子將農業銀行的100元轉到老劉農業銀行卡,主要有以下三步

1.首先判斷老王的農業銀行的賬戶金額是否大于100元

2.老王的農業銀行的賬戶余額減去100元

3.老劉的農業銀行的賬戶余額加100元

試想一下如果其中某一步失敗就會導致非常嚴重的問題,我們需要把操作放到一個事務中去執行,如果其中有一步執行失敗,那么所有操作都將回滾,通過這種方式來保證數據一致性。

?start transaction;select balance from account where uid = 60610;update account set balance = balance - 100 where uid = 60610;update account set balance = balance + 100 where uid = 60611;commit;

原子性(atomicity)

原子在化學中表示不可再進行分割的基本微粒,在事務表示的是這是一個不能再被分割的最小工作單元,整個事務的所有操作,要么全部成功,要么全部失敗回滾,而不可能僅僅執行某一部分。

一致性(consistency)

數據庫總是從一個一致性的狀態轉化到另一個一致性的狀態,老王轉賬即使第二步和第三步之間系統崩潰了,也不會出現問題,因為數據并沒有提交,沒有提交事務,所做的修改也并不會保存到數據庫中。

隔離性(isolation)

通常來說,一個事務所做的修改在最終提交前,對其他的事務是不可見的,這里為什么說“通常是不可見的”,因為這和具體的事務隔離級別有關,后面我們會進行分析。

持久性(durability)

一旦事務提交,則其他的修改就會永遠保存到數據庫中。即使系統崩潰,修改的數據也不會丟失。

02事務隔離級別

事務隔離級別

所謂事務隔離級別,就是用來定義一個事務所做的修改,哪些在事務內和事務間是可見的,哪些是不可見的。較低級別的隔離通常可以執行更高的并發,系統開銷也更低 。

在MySQL中一共有四種事務隔離級別:讀未提交、讀提交、可重復讀、可串行化,下面我們將分別簡單介紹四種隔離級別。

讀未提交 read uncommitted

在此事務隔離級別下,修改數據庫中的數據,即使沒有提交,對其他事務也是可見的。事務可以讀到未被提交的數據,這種情況也被稱為臟讀,這種隔離級別下會出現很多問題,但性能也不會比read committed好太多。

讀提交 read committed

大多的數據庫的默認事務隔離都是讀提交,但是MySQL的默認事務隔離基本是可重復讀,在這種隔離級別下,只有當事務提交后,事務中的修改才會對其他事務可見,但是會出現在同一個事務中多次查詢數據結果可能不同,因為中間可能有修改數據的事務提交了,這種現象叫不可重復讀

可重復讀 repeatable read

該級別不僅解決了臟讀,還可以在一個事務中,同一個事務多次讀取同樣的記錄結果是一樣,但是理論上,還是無法解決幻讀現象,所謂幻讀,就是在一個事務執行中,其他事務插入了新的行并且提交,就會產生幻行。但實際上MySQL通過MVCC(多版本并發控制)解決了幻讀的問題。

可串行化 serializable

該級別是最高的隔離級別,避免了前面說的幻讀的問題,顧名思義是對于同一行記錄,“寫”會加“寫鎖”,“讀”會加“讀鎖”。當出現讀寫鎖沖突的時候,后訪問的事務必須等前一個事務執行完成,才能繼續執行。實際中很少使用這個隔離級別,因為使用這個隔離級別,幾乎沒有并發可言。

各個事務級別對應的能力

03驗證事務隔離級別

MySQL基礎設置

首先登錄MySQL。

查看當前數據庫

創建測試數據庫

可以看到剛剛新建的數據庫

使用剛剛創建的數據庫

創建測試表

?create table tb_user ( id bigint not null auto_increment comment "用戶id", name varchar(50) not null comment "用戶姓名", ? age int not null comment "用戶年齡", ? balance int not null comment "用戶余額",PRIMARY KEY (`id`))ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COMMENT='用戶表';

初始化數據

SQL數據

?insert into tb_user(name, age, balance) values('老王', 24, 100);insert into tb_user(name, age, balance) values('老劉', 25, 500);

測試之前做的一些準備

MySQL中默認的是事務自動提交的,在測試我們需要控制事務提交的時機,所以我們將MySQL改為非自動提交事務,這種方式僅僅是當前session關閉自動提交。

設置全局關閉自動提交

查看自動提交事務狀態,可以看到當前session和全局的自動提交都已經關閉。

驗證讀未提交 read uncommitted

這里我們約定,每次測試完成后都將余額還原成初始值,即老王余額100元,老劉余額500元。

因為MySQL的默認事務隔離級別是可重復讀,我們先將當前session的事務隔離級別設置為讀未提交。

修改之后的事務隔離級別

下面啟動兩個事務A、B并設置它們的事務隔離級別為讀未提交。

開啟事務A和事務B

事務A查詢老王的余額(下圖應是查詢結果)

老王充值50元

事務B讀到了未提交的數據,出現了臟讀。

事務A回滾

老王賬戶減少150元,并提交事務B

此時查看老王的賬戶余額可以發現為-50,可以看出由臟讀引發的問題。

驗證讀已提交 read committed

首先我們需要把數據進行初始化,即老王余額100元,老劉余額500元。將兩個session的事務隔離級別設置為讀已提交。

讓事務A、B依次執行測試讀未提交時的邏輯,同樣的條件下,在讀已提交的情況下,事務B并沒有讀到臟數據。

接下來,我們做下一組測試,事務A和事務B按照下面的順序進行執行。

事務B查詢老劉賬戶余額為500元。

事務A向老劉賬戶充值500元并提交事務。

事務B再次查詢老劉的余額,為1000元,在同一個事務中,重復進行查詢返回的結果不同,這就是不可重復讀。

可重復讀 repeatable read

首先我們需要把數據進行初始化,即老王余額100元,老劉余額500元。將兩個session的事務隔離級別設置為可重復讀。

下面我們啟動事務A、B,重新按順序執行讀已提交的測試邏輯,通過測試我們發現,在可重復讀級別下,在同一個事務中多次查詢結果是一致的,解決了不可重復讀。


接下來,我們來看另一組測試,把數據進行初始化,即老王余額100元,老劉余額500元。

查詢當前用戶表中有幾個用戶,可以看到查詢到了兩個用戶。

在事務B中插入用戶老趙,并提交事務,此時數據中應該有三條記錄。

在事務A中查詢數據庫記錄條數,我們發現記錄數還是2,說明MySQL在repeatable read級別成功避免了幻讀,那么MySQL是如何在RR級別避免幻讀的呢?下文會進行分析。

驗證可串行化 serializable

這里沒有對可串行化 serializable隔離級別進行驗證,因為在此隔離級別會給所有的讀取行加鎖,所有事務只能串行執行。

04MVCC如何解決幻讀問題

MVCC(Multiversion Concurrency Control)即多版本并發控制,大多數的數據庫都實現了MVCC,但是實現機制各不相同,并且沒有統一的標準。

以InnoDB引擎為例,對MVCC的工作流程進行講解。

在使用InnoDB引擎的表中是通過在每條記錄后面保存兩個隱藏的列來實現的。這兩個列,一個保存了行的創建的時間,另一個保存行的刪除時間。

這里其實保存的并不是創建時間,而是系統的版本號(system version number)。每開始一個新事務,系統版本號都會自動遞增,事務開始時刻的系統版本號會作為事務的版本號,用來和查詢到的每行記錄版本號進行比較。

下面通過在repeatable read隔離級別下,對于增刪改查MVCC是如何操作的。

SELECT查詢

InnoDB會根據兩個條件去檢查每行記錄。

1、InnoDB只查版本早于當前事務的數據行(也就是,行的創建版本號小于或者等于事務的系統版本號),這樣做是為了保證,事務讀取的行,要么是事務開始前已經存在了,要么是事務自身插入或者修改過的。

2、關于行的刪除版本,我們讀取的行,要么沒有定義,要么大于當前事務的系統版本號(這說明是事務開啟之后修改的),這樣就可以確保我們讀取到的數據,都是在事務開啟之前未刪除。

這也就解釋了為什么在可重復級別可以避免幻讀,等同于給數據庫的表和數據做了一個快照,相當于在一個視圖上進行操作,無論其他事務怎么修改數據,在當前事務提交之前,多次查詢的結果都是相同的,除此之外我們可以發現,在數據庫中同一條記錄可能存在多個版本。

INSERT插入

InnoDB為新插入的每一行保存當前事務的系統版本號,作為行的創建版本號。

DELETE刪除

InnoDB為刪除的每一行保存當前事務的系統版本號,作為行刪除標記。

UPDATE更新

InnoDB為插入一行新記錄,保存當前事務系統版本號作為行的創建版本號,同時保存當前事務的系統版本號作為行刪除標記。

關于MVCC

通過上述介紹的機制,通過兩個額外的版本號字段,使得大多數的讀操作不需要加鎖,這樣設計使得讀數據操作很簡單,性能很好,但是需要額外的存儲空間,并且需要更多的檢查和維護工作。

此外,MVCC只在REPEATABLE READ和READ COMMITTED兩個隔離級別下工作。其他兩個隔離級別和MVCC都不兼容,因為讀未提交總是讀取最新的數據行,而可串行化則會對所有行都加鎖。

05總結

本文主要介紹了,MySQL的事務的特性ACID,除此還介紹了事務的各個隔離級別的特征,不同的隔離級別會出現什么樣的問題,理論上,事務的隔離級別越高消耗的資源越多,在平時的業務開發中,需要根據業務特點去選擇不同的事務隔離級別,最后我們介紹了MVCC,并說明它如何解決幻讀問題的,以及MVCC在可重復讀下,增刪改查的操作,希望讀者能夠掌握本文的內容,相信對理解MySQL的事務會有一定的幫助。

總結

以上是生活随笔為你收集整理的mysql查看版本号_十分钟了解MySQL事务机制的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。