欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Mysql案例刨析事務(wù)隔離級別

 更新時間:2021年09月23日 11:49:05   作者:_江南一點雨  
隔離性其實比想象要復(fù)雜。在SQL中定義了四種隔離的級別,每一種隔離級別都規(guī)定了一個事務(wù)中的修改,哪些是在事務(wù)內(nèi)和事務(wù)間是可見的,哪些是不可見的。較低級別的隔離通常來說能承受更高的并發(fā),系統(tǒng)的開銷也會更小

很多小伙伴對 MySQL 的隔離級別一直心存疑惑,其實這個問題一點都不難,關(guān)鍵看怎么講!單純的看理論,絕對讓你暈頭轉(zhuǎn)向,但是,如果我們通過幾個實際的 SQL 來演示一些,大家就會發(fā)現(xiàn)這玩意原來這么簡單!

今天松哥想通過幾個簡單的案例,來和大家演示一下 MySQL 中的事務(wù)隔離級別問題。

1. 理論

MySQL 中事務(wù)的隔離級別一共分為四種,分別如下:

  • 序列化(SERIALIZABLE)
  • 可重復(fù)讀(REPEATABLE READ)
  • 提交讀(READ COMMITTED)
  • 未提交讀(READ UNCOMMITTED)

四種不同的隔離級別含義分別如下:

SERIALIZABLE

如果隔離級別為序列化,則用戶之間通過一個接一個順序地執(zhí)行當前的事務(wù),這種隔離級別提供了事務(wù)之間最大限度的隔離。

REPEATABLE READ

在可重復(fù)讀在這一隔離級別上,事務(wù)不會被看成是一個序列。不過,當前正在執(zhí)行事務(wù)的變化仍然不能被外部看到,也就是說,如果用戶在另外一個事務(wù)中執(zhí)行同條 SELECT 語句數(shù)次,結(jié)果總是相同的。(因為正在執(zhí)行的事務(wù)所產(chǎn)生的數(shù)據(jù)變化不能被外部看到)。

READ COMMITTED

READ COMMITTED 隔離級別的安全性比 REPEATABLE READ 隔離級別的安全性要差。處于 READ COMMITTED 級別的事務(wù)可以看到其他事務(wù)對數(shù)據(jù)的修改。也就是說,在事務(wù)處理期間,如果其他事務(wù)修改了相應(yīng)的表,那么同一個事務(wù)的多個 SELECT 語句可能返回不同的結(jié)果。

READ UNCOMMITTED

READ UNCOMMITTED 提供了事務(wù)之間最小限度的隔離。除了容易產(chǎn)生虛幻的讀操作和不能重復(fù)的讀操作外,處于這個隔離級的事務(wù)可以讀到其他事務(wù)還沒有提交的數(shù)據(jù),如果這個事務(wù)使用其他事務(wù)不提交的變化作為計算的基礎(chǔ),然后那些未提交的變化被它們的父事務(wù)撤銷,這就導致了大量的數(shù)據(jù)變化。

在 MySQL 數(shù)據(jù)庫種,默認的事務(wù)隔離級別是 REPEATABLE READ

2. SQL 實踐

接下來通過幾條簡單的 SQL 向讀者驗證上面的理論。

2.1 查看隔離級別

通過如下 SQL 可以查看數(shù)據(jù)庫實例默認的全局隔離級別和當前 session 的隔離級別:

MySQL8 之前使用如下命令查看 MySQL 隔離級別:

SELECT @@GLOBAL.tx_isolation, @@tx_isolation;

查詢結(jié)果如圖:

可以看到,默認的隔離級別為 REPEATABLE-READ,全局隔離級別和當前會話隔離級別皆是如此。

MySQL8 開始,通過如下命令查看 MySQL 默認隔離級別:

SELECT @@GLOBAL.transaction_isolation, @@transaction_isolation;

就是關(guān)鍵字變了,其他都一樣。

通過如下命令可以修改隔離級別(建議開發(fā)者在修改時修改當前 session 隔離級別即可,不用修改全局的隔離級別):

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

上面這條 SQL 表示將當前 session 的數(shù)據(jù)庫隔離級別設(shè)置為 READ UNCOMMITTED,設(shè)置成功后,再次查詢隔離級別,發(fā)現(xiàn)當前 session 的隔離級別已經(jīng)變了,如圖1-2:

注意,如果只是修改了當前 session 的隔離級別,則換一個 session 之后,隔離級別又會恢復(fù)到默認的隔離級別,所以我們測試時,修改當前 session 的隔離級別即可。

2.2 READ UNCOMMITTED

2.2.1 準備測試數(shù)據(jù)

READ UNCOMMITTED 是最低隔離級別,這種隔離級別中存在臟讀、不可重復(fù)讀以及幻象讀問題,所以這里我們先來看這個隔離級別,借此大家可以搞懂這三個問題到底是怎么回事。

下面分別予以介紹。

首先創(chuàng)建一個簡單的表,預(yù)設(shè)兩條數(shù)據(jù),如下:

表的數(shù)據(jù)很簡單,有 javaboy 和 itboyhub 兩個用戶,兩個人的賬戶各有 1000 人民幣?,F(xiàn)在模擬這兩個用戶之間的一個轉(zhuǎn)賬操作。

注意,如果讀者使用的是 Navicat 的話,不同的查詢窗口就對應(yīng)了不同的 session,如果讀者使用了 SQLyog 的話,不同查詢窗口對應(yīng)同一個 session,因此如果使用 SQLyog,需要讀者再開啟一個新的連接,在新的連接中進行查詢操作。

2.2.2 臟讀

一個事務(wù)讀到另外一個事務(wù)還沒有提交的數(shù)據(jù),稱之為臟讀。具體操作如下:

首先打開兩個SQL操作窗口,假設(shè)分別為 A 和 B,在 A 窗口中輸入如下幾條 SQL (輸入完成后不用執(zhí)行):

START TRANSACTION;
UPDATE account set balance=balance+100 where name='javaboy';
UPDATE account set balance=balance-100 where name='itboyhub';
COMMIT;

在 B 窗口執(zhí)行如下 SQL,修改默認的事務(wù)隔離級別為 READ UNCOMMITTED,如下:

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

接下來在 B 窗口中輸入如下 SQL,輸入完成后,首先執(zhí)行第一行開啟事務(wù)(注意只需要執(zhí)行一行即可):

START TRANSACTION;
SELECT * from account;
COMMIT;

接下來執(zhí)行 A 窗口中的前兩條 SQL,即開啟事務(wù),給 javaboy 這個賬戶添加 100 元。

進入到 B 窗口,執(zhí)行 B 窗口的第二條查詢 SQL(SELECT * from user;),結(jié)果如下:

可以看到,A 窗口中的事務(wù),雖然還未提交,但是 B 窗口中已經(jīng)可以查詢到數(shù)據(jù)的相關(guān)變化了。

這就是臟讀問題。

2.2.3 不可重復(fù)讀

不可重復(fù)讀是指一個事務(wù)先后讀取同一條記錄,但兩次讀取的數(shù)據(jù)不同,稱之為不可重復(fù)讀。具體操作步驟如下(操作之前先將兩個賬戶的錢都恢復(fù)為1000):

  1. 首先打開兩個查詢窗口 A 和 B ,并且將 B 的數(shù)據(jù)庫事務(wù)隔離級別設(shè)置為 READ UNCOMMITTED。具體 SQL 參考上文,這里不贅述。
  2. 在 B 窗口中輸入如下 SQL,然后只執(zhí)行前兩條 SQL 開啟事務(wù)并查詢 javaboy 的賬戶:
START TRANSACTION;
SELECT * from account where name='javaboy';
COMMIT;

前兩條 SQL 執(zhí)行結(jié)果如下:

在 A 窗口中執(zhí)行如下 SQL,給 javaboy 這個賬戶添加 100 塊錢,如下:

START TRANSACTION;
UPDATE account set balance=balance+100 where name='javaboy';
COMMIT;

4.再次回到 B 窗口,執(zhí)行 B 窗口的第二條 SQL 查看 javaboy 的賬戶,結(jié)果如下:

javaboy 的賬戶已經(jīng)發(fā)生了變化,即前后兩次查看 javaboy 賬戶,結(jié)果不一致,這就是不可重復(fù)讀。

和臟讀的區(qū)別在于,臟讀是看到了其他事務(wù)未提交的數(shù)據(jù),而不可重復(fù)讀是看到了其他事務(wù)已經(jīng)提交的數(shù)據(jù)(由于當前 SQL 也是在事務(wù)中,因此有可能并不想看到其他事務(wù)已經(jīng)提交的數(shù)據(jù))。

2.2.4 幻象讀

幻象讀和不可重復(fù)讀非常像,看名字就是產(chǎn)生幻覺了。

我舉一個簡單例子。

在 A 窗口中輸入如下 SQL:

START TRANSACTION;
insert into account(name,balance) values('zhangsan',1000);
COMMIT;

然后在 B 窗口輸入如下 SQL:

START TRANSACTION;
SELECT * from account;
delete from account where name='zhangsan';
COMMIT;

我們執(zhí)行步驟如下:

  • 首先執(zhí)行 B 窗口的前兩行,開啟一個事務(wù),同時查詢數(shù)據(jù)庫中的數(shù)據(jù),此時查詢到的數(shù)據(jù)只有 javaboy 和 itboyhub。
  • 執(zhí)行 A 窗口的前兩行,向數(shù)據(jù)庫中添加一個名為 zhangsan 的用戶,注意不用提交事務(wù)。
  • 執(zhí)行 B 窗口的第二行,由于臟讀問題,此時可以查詢到 zhangsan 這個用戶。
  • 執(zhí)行 B 窗口的第三行,去刪除 name 為 zhangsan 的記錄,這個時候刪除就會出問題,雖然在 B 窗口中可以查詢到 zhangsan,但是這條記錄還沒有提交,是因為臟讀的原因才看到了,所以是沒法刪除的。此時就產(chǎn)生了幻覺,明明有個 zhangsan,卻無法刪除。

這就是幻讀。

看了上面的案例,大家應(yīng)該明白了臟讀、不可重復(fù)讀以及幻讀各自是什么含義了。

2.3 READ COMMITTED

和 READ UNCOMMITTED 相比,READ COMMITTED 主要解決了臟讀的問題,對于不可重復(fù)讀和幻象讀則未解決。

將事務(wù)的隔離級別改為 READ COMMITTED 之后,重復(fù)上面關(guān)于臟讀案例的測試,發(fā)現(xiàn)已經(jīng)不存在臟讀問題了;重復(fù)上面關(guān)于不可重復(fù)讀案例的測試,發(fā)現(xiàn)不可重復(fù)讀問題依然存在。

上面那個案例不適用于幻讀的測試,我們換一個幻讀的測試案例。

還是兩個窗口 A 和 B,將 B 窗口的隔離級別改為 READ COMMITTED

然后在 A 窗口輸入如下測試 SQL:

START TRANSACTION;
insert into account(name,balance) values('zhangsan',1000);
COMMIT;

在 B 窗口輸入如下測試 SQL:

START TRANSACTION;
SELECT * from account;
insert into account(name,balance) values('zhangsan',1000);
COMMIT;

測試方式如下:

  • 首先執(zhí)行 B 窗口的前兩行 SQL,開啟事務(wù)并查詢數(shù)據(jù),此時查到的只有 javaboy 和 itboyhub 兩個用戶。
  • 執(zhí)行 A 窗口的前兩行 SQL,插入一條記錄,但是并不提交事務(wù)。
  • 執(zhí)行 B 窗口的第二行 SQL,由于現(xiàn)在已經(jīng)沒有了臟讀問題,所以此時查不到 A 窗口中添加的數(shù)據(jù)。
  • 執(zhí)行 B 窗口的第三行 SQL,由于 name 字段唯一,因此這里會無法插入。此時就產(chǎn)生幻覺了,明明沒有 zhangsan 這個用戶,卻無法插入 zhangsan。

2.4 REPEATABLE READ

和 READ COMMITTED 相比,REPEATABLE READ 進一步解決了不可重復(fù)讀的問題,但是幻象讀則未解決。

REPEATABLE READ 中關(guān)于幻讀的測試和上一小節(jié)基本一致,不同的是第二步中執(zhí)行完插入 SQL 后記得提交事務(wù)。

由于 REPEATABLE READ 已經(jīng)解決了不可重復(fù)讀,因此第二步即使提交了事務(wù),第三步也查不到已經(jīng)提交的數(shù)據(jù),第四步繼續(xù)插入就會出錯。

注意,REPEATABLE READ 也是 InnoDB 引擎的默認數(shù)據(jù)庫事務(wù)隔離級別

2.5 SERIALIZABLE

SERIALIZABLE 提供了事務(wù)之間最大限度的隔離,在這種隔離級別中,事務(wù)一個接一個順序的執(zhí)行,不會發(fā)生臟讀、不可重復(fù)讀以及幻象讀問題,最安全。

如果設(shè)置當前事務(wù)隔離級別為 SERIALIZABLE,那么此時開啟其他事務(wù)時,就會阻塞,必須等當前事務(wù)提交了,其他事務(wù)才能開啟成功,因此前面的臟讀、不可重復(fù)讀以及幻象讀問題這里都不會發(fā)生。

3. 總結(jié)

總的來說,隔離級別和臟讀、不可重復(fù)讀以及幻象讀的對應(yīng)關(guān)系如下:

隔離級別 臟讀 不可重復(fù)讀 幻象讀
READ UNCOMMITTED 允許 允許 允許
READ COMMITED 不允許 允許 允許
REPEATABLE READ 不允許 不允許 允許
SERIALIZABLE 不允許 不允許 不允許

性能關(guān)系如圖:

好了,這篇文章就和小伙伴們先說這么多,大家不妨寫幾行 SQL 試一試。

到此這篇關(guān)于Mysql案例刨析事務(wù)隔離級別的文章就介紹到這了,更多相關(guān)Mysql 事務(wù)隔離級別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SQLyog錯誤號碼2058最新解決辦法

    SQLyog錯誤號碼2058最新解決辦法

    這篇文章主要給大家介紹了關(guān)于SQLyog錯誤號碼2058的最新解決辦法,使用sqlyog連接數(shù)據(jù)庫過程中可能會出現(xiàn)2058錯誤,出現(xiàn)的原因是因為MYSQL8.0對密碼的加密方式進行了改變,需要的朋友可以參考下
    2023-08-08
  • MySQL分區(qū)表的使用

    MySQL分區(qū)表的使用

    本文詳細介紹了在MySQL中創(chuàng)建分區(qū)表的方法和注意事項,包括Range和List兩種常見分區(qū)類型的具體操作流程,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-10-10
  • 阿里云云服務(wù)器mysql密碼找回的方法

    阿里云云服務(wù)器mysql密碼找回的方法

    這篇文章主要介紹了阿里云云服務(wù)器mysql密碼找回的方法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-07-07
  • 淺析MySQL 鎖和事務(wù)

    淺析MySQL 鎖和事務(wù)

    這篇文章主要介紹了MySQL 鎖和事務(wù)的相關(guān)資料,幫助大家更好的理解和使用MySQL數(shù)據(jù)庫,感興趣的朋友可以了解下
    2020-09-09
  • MySQL定期整理磁盤碎片的方法實現(xiàn)

    MySQL定期整理磁盤碎片的方法實現(xiàn)

    磁盤碎片是指文件在磁盤上分散存儲的情況,這可能導致磁盤讀寫速度下降、空間浪費等問題,本文主要介紹了MySQL定期整理磁盤碎片的方法實現(xiàn),感興趣的可以了解一下
    2024-02-02
  • mysql enum字段類型的謹慎使用

    mysql enum字段類型的謹慎使用

    本文主要介紹了mysql enum字段類型使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07
  • MySQL表的增刪改查(CRUD)

    MySQL表的增刪改查(CRUD)

    這篇文章主要介紹了如何對數(shù)據(jù)庫增刪改查,想要更全面了解的小伙伴,可以詳細閱讀本文
    2023-03-03
  • MySQL數(shù)據(jù)庫命令

    MySQL數(shù)據(jù)庫命令

    這篇文章主要介紹了數(shù)據(jù)庫的常用命令,數(shù)據(jù)庫中對表的命令以及一些常用的數(shù)據(jù)庫查詢和常用函數(shù),感興趣的小伙伴可以借鑒一下
    2023-03-03
  • mysql 8.0 錯誤The server requested authentication method unknown to the client解決方法

    mysql 8.0 錯誤The server requested authentication method unkno

    在本篇文章里小編給大家整理的是關(guān)于mysql 8.0 錯誤The server requested authentication method unknown to the client解決方法,有此需要的朋友們可以學習下。
    2019-08-08
  • mysql 5.7.18 Installer安裝下載圖文教程

    mysql 5.7.18 Installer安裝下載圖文教程

    這篇文章主要為大家詳細介紹了mysql 5.7.18 Installer安裝下載圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-09-09

最新評論