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

全面解析MySQL中的隔離級(jí)別

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

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

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

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

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

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

事務(wù)隔離級(jí)別:

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

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

先加創(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);

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

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

讀未提交測(cè)試:

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

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

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

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

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

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

讀已提交測(cè)試:

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

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

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

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

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

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

可重復(fù)讀測(cè)試:

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

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

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

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

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

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

B客戶端重新開(kāi)啟事務(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í)行過(guò)程:# 設(shè)置隔離級(jí)別可重復(fù)度MySQL [test]> set tx_isolation='repeatable-read';
Query OK, 0 rows affected, 1 warning (0.00 sec)
# 開(kāi)啟事務(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)
# 再次查詢驗(yàn)證兩次結(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í)行過(guò)程:設(shè)置隔離級(jí)別可重復(fù)讀
MySQL [test]> set tx_isolation='repeatable-read';
Query OK, 0 rows affected, 1 warning (0.00 sec)
# 開(kāi)啟事務(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)
# 再次開(kāi)啟事務(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';可自行驗(yàn)證,能解決上面所有問(wèn)題,但是一般不會(huì)用到的,保證一致性的同時(shí)帶來(lái)的是性能大幅度下降,并發(fā)性極低,默認(rèn)是可重復(fù)讀。

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

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

相關(guān)文章

  • Centos7 如何部署MySQL8.0.30數(shù)據(jù)庫(kù)

    Centos7 如何部署MySQL8.0.30數(shù)據(jù)庫(kù)

    這篇文章主要介紹了Centos7 如何部署MySQL8.0.30數(shù)據(jù)庫(kù),本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧
    2024-05-05
  • mysql存儲(chǔ)過(guò)程原理與使用方法詳解

    mysql存儲(chǔ)過(guò)程原理與使用方法詳解

    這篇文章主要介紹了mysql存儲(chǔ)過(guò)程原理與使用方法,結(jié)合實(shí)例形式詳細(xì)分析了mysql存儲(chǔ)過(guò)程的優(yōu)缺點(diǎn)、定義、調(diào)用方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2019-12-12
  • 具有負(fù)載均衡功能的MySQL服務(wù)器集群部署及實(shí)現(xiàn)

    具有負(fù)載均衡功能的MySQL服務(wù)器集群部署及實(shí)現(xiàn)

    MySQL是一個(gè)高速度、高性能、多線程的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),適用平臺(tái)多,可擴(kuò)展性強(qiáng)。
    2011-05-05
  • MySQL按照漢字的拼音排序簡(jiǎn)單實(shí)例

    MySQL按照漢字的拼音排序簡(jiǎn)單實(shí)例

    下面小編就為大家?guī)?lái)一篇MySQL按照漢字的拼音排序簡(jiǎn)單實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-01-01
  • SQL中"1=1"的陷阱:為什么應(yīng)避免使用

    SQL中"1=1"的陷阱:為什么應(yīng)避免使用

    "1=1"在SQL中可能看似無(wú)害,但它卻是一個(gè)隱藏的陷阱,這個(gè)簡(jiǎn)單的表達(dá)式可能會(huì)導(dǎo)致你的查詢結(jié)果出現(xiàn)偏差,甚至可能引發(fā)安全問(wèn)題,本指南將揭示這個(gè)陷阱,教你如何避免使用"1=1",讓你的數(shù)據(jù)庫(kù)操作更加安全、準(zhǔn)確,讓我們一起揭開(kāi)"1=1"的秘密,提升你的SQL技能!
    2024-02-02
  • MySql 5.5.29綠色安裝教程詳解

    MySql 5.5.29綠色安裝教程詳解

    本文給大家介紹mysql5.5.29綠色安裝教程,本文給大家介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友參考下
    2017-01-01
  • Mysql 獲取表的comment 字段操作

    Mysql 獲取表的comment 字段操作

    這篇文章主要介紹了Mysql 獲取表的comment 字段操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-01-01
  • 101個(gè)MySQL優(yōu)化技巧和提示

    101個(gè)MySQL優(yōu)化技巧和提示

    人們一直在推動(dòng)MySQL發(fā)展到它的極限。這里是101條調(diào)節(jié)和優(yōu)化MySQL安裝的技巧。一些技巧是針對(duì)特定的安裝環(huán)境的,但這些思路是通用的。我已經(jīng)把他們分成幾類(lèi),來(lái)幫助你掌握更多MySQL的調(diào)節(jié)和優(yōu)化技巧。
    2014-02-02
  • mysql 5.7.18 免安裝版window配置方法

    mysql 5.7.18 免安裝版window配置方法

    這篇文章主要為大家詳細(xì)介紹了mysql 5.7.18 免安裝版window配置方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • MySQL中的隱藏列的具體查看

    MySQL中的隱藏列的具體查看

    mysql中存在一些隱藏列,例如行標(biāo)識(shí)、事務(wù)ID、回滾指針等,不知道大家是否和我一樣好奇過(guò),要怎樣才能實(shí)際地看到這些隱藏列的值呢,感興趣的可以了解一下
    2021-09-09

最新評(píng)論