最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

全面解析MySQL中的隔離級別

 更新時間:2021年01月21日 15:35:21   作者:以戰(zhàn)止殤  
這篇文章主要介紹了MySQL中的隔離級別的相關(guān)資料,幫助大家更好的理解和使用MySQL,感興趣的朋友可以了解下。

  數(shù)據(jù)庫并發(fā)的對同一批數(shù)據(jù)進行增刪改,就可能會出現(xiàn)我們所說的臟寫、臟讀、不可重復(fù)讀、幻讀等一系列問題。MySQL提供了一系列機制來解決事務(wù)并發(fā)問題,比如事務(wù)隔離、鎖機制、MVCC多版本并發(fā)控制機制。今天來探究一下事務(wù)隔離機制。

事務(wù)是一組SQL組成的邏輯處理單元,先來看下事務(wù)的ACID特性:

  • 原子性(Atomicity) :事務(wù)是一個原子操作單元,對數(shù)據(jù)進行修改,要么全執(zhí)行要么全不執(zhí)行。是從執(zhí)行層面上來描述的。
  • 一致性(Consistent) :在事務(wù)開始和完成時,數(shù)據(jù)都必須保持一致狀態(tài)。是從執(zhí)行結(jié)果層面上來描述的。
  • 隔離性(Isolation) :數(shù)據(jù)庫系統(tǒng)提供一定的隔離機制,保證事務(wù)執(zhí)行過程中對外部不可見,獨立運行,不受外部影響。
  • 持久性(Durable) :事務(wù)完成之后,它對于數(shù)據(jù)的修改是永久性的,即使出現(xiàn)系統(tǒng)故障也能夠保持。

并發(fā)事務(wù)的影響:

  • 臟寫(更新丟失:Lost Update):多個事務(wù)選擇了同一行,彼此不知道對方存在,會覆蓋之前事務(wù)的數(shù)據(jù)操作。
  • 臟讀(Dirty Reads):A事務(wù)讀取了B事務(wù)未提交的數(shù)據(jù),B事務(wù)回滾,A提交,最終結(jié)果不符合一致性原則
  • 不可重讀(Non-Repeatable Reads):同一個事務(wù),相同的查詢語句,執(zhí)行多次結(jié)果不一致,可能是外部事務(wù)修改導(dǎo)致的,不符合隔離性。
  • 幻讀(Phantom Reads):事務(wù)A讀取到了事務(wù)B提交的新增數(shù)據(jù),不符合隔離性

事務(wù)隔離級別:

隔離級別  臟讀(Dirty Read) 不可重復(fù)讀(NonRepeatable Read) 幻讀(Phantom Read)
讀未提交(Read uncommitted) 可能 可能 可能
讀已提交(Read committed) 不可能 可能 可能
可重復(fù)讀(Repeatable Read) 不可能 不可能 可能
串行化(Serializable) 不可能 不可能 不可能

MySQL提供了上面四種隔離級別,隔離越嚴格,可能出現(xiàn)的問題就越少,但付出的性能代價就越大,默認的隔離級別是可重復(fù)讀。下面使用客戶端進行操作進行驗證。

先加創(chuàng)建一張表和數(shù)據(jù)

CREATE TABLE `account` (
 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `balance` int(11) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO `account` (`id`, `balance`)
VALUES
  (1, 500),
  (2, 600),
  (3, 200);

連接客戶端,查看隔離級別,可以看到是可重復(fù)讀:

MySQL [test]> show variables like 'tx_isolation';
+---------------+-----------------+
| Variable_name | Value      |
+---------------+-----------------+
| tx_isolation | REPEATABLE-READ |
+---------------+-----------------+

讀未提交測試:

AB客戶端都執(zhí)行set tx_isolation='read-uncommitted';設(shè)置隔離級別為讀未提交。

A客戶端開啟事務(wù):start transaction;查詢數(shù)據(jù):select * from account;

B客戶端開啟事務(wù):start transaction;更新數(shù)據(jù):update account set balance = balance - 100 where id = 1;此時事務(wù)未提交

A客戶端再次查詢數(shù)據(jù):select * from account; 此時看到兩次查詢的數(shù)據(jù)已經(jīng)不一樣了

在B沒提交前A就讀到了B更新的數(shù)據(jù),此時如果B回滾,那么A那邊就是臟數(shù)據(jù)。這種情況就是讀未提交造成的臟讀。用讀已提交隔離級別可以解決。

使用commit命令把AB客戶端的事務(wù)提交。

讀已提交測試:

AB客戶端都執(zhí)行  set tx_isolation='read-committed'; 設(shè)置隔離級別為讀已提交。

A客戶端開啟事務(wù):start transaction;查詢數(shù)據(jù):select * from account;

B客戶端開啟事務(wù):start transaction;更新數(shù)據(jù):update account set balance = balance - 100 where id = 1;此時事務(wù)未提交

A客戶端再次查詢數(shù)據(jù):select * from account; 此時看到A客戶端兩次查詢數(shù)據(jù)一致,未出現(xiàn)臟讀情況

此時B客戶端事務(wù)提交:commit;

A客戶端再次查詢數(shù)據(jù):select * from account; 此時看到A客戶端查詢數(shù)據(jù)已經(jīng)發(fā)生了變化,這就是不可重復(fù)讀。

可重復(fù)讀測試:

AB客戶端都執(zhí)行  set tx_isolation='repeatable-read'; 設(shè)置隔離級別為可重復(fù)讀。

A客戶端開啟事務(wù):start transaction;查詢數(shù)據(jù):select * from account;

B客戶端開啟事務(wù):start transaction;更新數(shù)據(jù):update account set balance = balance - 100 where id = 1; commit提交事務(wù)

A客戶端再次查詢數(shù)據(jù):select * from account; 此時看到A客戶端兩次查詢數(shù)據(jù)一致,重復(fù)讀取數(shù)據(jù)一致。

A客戶端執(zhí)行更新語句:update account set balance = balance - 50 where id = 1;

A客戶端再次查詢數(shù)據(jù):select * from account; 此時看到id=1的這條數(shù)據(jù)是B客戶端更新之后的數(shù)據(jù)-50,數(shù)據(jù)的一致性沒有被破壞

B客戶端重新開啟事務(wù),插入一條數(shù)據(jù):insert into account(id,balance) values (4,1000); commit提交事務(wù);

A客戶端查詢,和上次結(jié)果一致

A客戶端執(zhí)行:update account set balance = balance - 100 where id = 4; 更新B客戶端新插入的數(shù)據(jù),能執(zhí)行成功,再次查詢所有數(shù)據(jù),能插到id=4的數(shù)據(jù),出現(xiàn)幻讀。

# A客戶端執(zhí)行過程:# 設(shè)置隔離級別可重復(fù)度MySQL [test]> set tx_isolation='repeatable-read';
Query OK, 0 rows affected, 1 warning (0.00 sec)
# 開啟事務(wù)
MySQL [test]> start transaction;
Query OK, 0 rows affected (0.00 sec)
# 查詢所有數(shù)據(jù)
MySQL [test]> select * from account;
+----+---------+
| id | balance |
+----+---------+
| 1 |   300 |
| 2 |   600 |
| 3 |   200 |
+----+---------+
3 rows in set (0.00 sec)
# 再次查詢驗證兩次結(jié)果是否一致
MySQL [test]> select * from account;
+----+---------+
| id | balance |
+----+---------+
| 1 |   300 |
| 2 |   600 |
| 3 |   200 |
+----+---------+
3 rows in set (0.00 sec)
# 在B客戶端插入數(shù)據(jù)之后,此次A客戶端不能查詢到
MySQL [test]> select * from account;
+----+---------+
| id | balance |
+----+---------+
| 1 |   150 |
| 2 |   600 |
| 3 |   200 |
+----+---------+
3 rows in set (0.00 sec)
# A客戶端更新B客戶端插入的數(shù)據(jù),發(fā)現(xiàn)可以更新成功
MySQL [test]> update account set balance = balance + 1000 where id = 4;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
# 再次查詢,能查詢到數(shù)據(jù),出現(xiàn)幻讀
MySQL [test]> select * from account;
+----+---------+
| id | balance |
+----+---------+
| 1 |   400 |
| 2 |   600 |
| 3 |   200 |
| 4 |  2000 |
+----+---------+
4 rows in set (0.00 sec)
# 提交事務(wù)
MySQL [test]> commit;
Query OK, 0 rows affected (0.01 sec)
# B客戶端執(zhí)行過程:設(shè)置隔離級別可重復(fù)讀
MySQL [test]> set tx_isolation='repeatable-read';
Query OK, 0 rows affected, 1 warning (0.00 sec)
# 開啟事務(wù)
MySQL [test]> start transaction;
Query OK, 0 rows affected (0.00 sec)
# 更新數(shù)據(jù),直接提交
MySQL [test]> update account set balance = balance - 100 where id = 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

MySQL [test]> commit;
Query OK, 0 rows affected (0.01 sec)
# 再次開啟事務(wù)
MySQL [test]> start transaction;
Query OK, 0 rows affected (0.00 sec)
# 插入一條數(shù)據(jù)
MySQL [test]> insert into account(id,balance) values (4,1000);
Query OK, 1 row affected (0.01 sec)
MySQL [test]> commit;
Query OK, 0 rows affected (0.00 sec)

最后一種串行化:set tx_isolation='serializable';可自行驗證,能解決上面所有問題,但是一般不會用到的,保證一致性的同時帶來的是性能大幅度下降,并發(fā)性極低,默認是可重復(fù)讀。

通過隔離級別在一定程度上能處理事務(wù)并發(fā)的問題,除此之外還有其他的手段,后續(xù)會再次探究。

以上就是全面解析MySQL中的隔離級別的詳細內(nèi)容,更多關(guān)于MySQL 隔離級別的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Mysql中復(fù)制詳細解析

    Mysql中復(fù)制詳細解析

    這篇文章主要介紹了Mysql中復(fù)制詳細解析,從基本概念、用途、實現(xiàn)方法以及集中模式進行了介紹,然后分享了具體實現(xiàn)代碼,具有一定參考價值,需要的朋友可以了解下。
    2017-10-10
  • 一文掌握MySQL唯一索引是如何加鎖的

    一文掌握MySQL唯一索引是如何加鎖的

    這篇文章主要介紹了一文掌握MySQL唯一索引是如何加鎖的,本案例其實就是在主鍵索引上進行等值查詢,取決于查詢記錄是否存在,存在退化成記錄鎖,否則就是在索引樹中找到第一個大于該查詢記錄的記錄后,將改記錄的索引中的next-key lock退換成間隙鎖,需要的朋友可以參考下
    2024-06-06
  • Mysql如何適當(dāng)?shù)奶砑铀饕榻B

    Mysql如何適當(dāng)?shù)奶砑铀饕榻B

    今天小編就為大家分享一篇關(guān)于Mysql如何適當(dāng)?shù)奶砑铀饕榻B,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • mysql高級學(xué)習(xí)之索引的優(yōu)劣勢及規(guī)則使用

    mysql高級學(xué)習(xí)之索引的優(yōu)劣勢及規(guī)則使用

    這篇文章主要給大家介紹了關(guān)于mysql高級學(xué)習(xí)之索引的優(yōu)劣勢及規(guī)則使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • mysql跨數(shù)據(jù)庫復(fù)制表(在同一IP地址中)示例

    mysql跨數(shù)據(jù)庫復(fù)制表(在同一IP地址中)示例

    這篇文章主要介紹了mysql跨數(shù)據(jù)庫復(fù)制表(在同一IP地址中)示例,需要的朋友可以參考下
    2014-03-03
  • MySQL定時任務(wù)(EVENT事件)如何配置詳解

    MySQL定時任務(wù)(EVENT事件)如何配置詳解

    這篇文章主要介紹了MySQL定時任務(wù)(EVENT事件)如何配置詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • mysql密碼忘記怎么辦

    mysql密碼忘記怎么辦

    mysql密碼忘記怎么辦?卸載重裝?這篇文章主要為大家詳細介紹了不卸載也能重新設(shè)置密碼的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • 從MySQL5.7平滑升級到MySQL8.0數(shù)據(jù)庫的最佳實踐教程

    從MySQL5.7平滑升級到MySQL8.0數(shù)據(jù)庫的最佳實踐教程

    這篇文章主要給大家介紹了關(guān)于從MySQL5.7平滑升級到MySQL8.0數(shù)據(jù)庫的最佳實踐,升級MySQL版本需要進行一系列操作,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2024-07-07
  • select?into?from和insert?into?select的區(qū)別舉例詳解

    select?into?from和insert?into?select的區(qū)別舉例詳解

    這篇文章主要介紹了SQL中的SELECT?INTO和INSERT?INTO?SELECT兩種語句的區(qū)別和用法,SELECT?INTO用于創(chuàng)建新表并復(fù)制數(shù)據(jù)到新表中,而INSERT?INTO?SELECT用于將數(shù)據(jù)從一個表插入到已存在的另一個表中,需要的朋友可以參考下
    2025-03-03
  • 解決MySQL錯誤碼:1054 Unknown column ‘**‘ in ‘field list‘的問題

    解決MySQL錯誤碼:1054 Unknown column ‘**‘ in&n

    這篇文章主要介紹了解決MySQL錯誤碼:1054 Unknown column ‘**‘ in ‘field list‘的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05

最新評論

九江县| 丹阳市| 新平| 井陉县| 弥勒县| 扶风县| 延长县| 潜山县| 仪陇县| 阜城县| 扶沟县| 四子王旗| 毕节市| 手游| 阜宁县| 聊城市| 米易县| 凯里市| 汉中市| 玛曲县| 屯门区| 龙井市| 资溪县| 同心县| 西藏| 专栏| 林口县| 罗源县| 通辽市| 正蓝旗| 三江| 上犹县| 南阳市| 乐陵市| 宁国市| 邵武市| 柳河县| 黔南| 布拖县| 沈丘县| 平顺县|