国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數據庫技術|

服務器之家 - 數據庫 - Mysql - MySQL四種事務隔離級別詳解

MySQL四種事務隔離級別詳解

2020-07-30 18:32花弄影 Mysql

這篇文章主要為大家詳細介紹了MySQL四種事務隔離級別的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實驗的測試環境:Windows 10+cmd+MySQL5.6.36+InnoDB

一、事務的基本要素(ACID)

  1、原子性(Atomicity):事務開始后所有操作,要么全部做完,要么全部不做,不可能停滯在中間環節。事務執行過程中出錯,會回滾到事務開始前的狀態,所有的操作就像沒有發生一樣。也就是說事務是一個不可分割的整體,就像化學中學過的原子,是物質構成的基本單位。

   2、一致性(Consistency):事務開始前和結束后,數據庫的完整性約束沒有被破壞 。比如A向B轉賬,不可能A扣了錢,B卻沒收到。

   3、隔離性(Isolation):同一時間,只允許一個事務請求同一數據,不同的事務之間彼此沒有任何干擾。比如A正在從一張銀行卡中取錢,在A取錢的過程結束前,B不能向這張卡轉賬。

   4、持久性(Durability):事務完成后,事務對數據庫的所有更新將被保存到數據庫,不能回滾。

  小結:原子性是事務隔離的基礎,隔離性和持久性是手段,最終目的是為了保持數據的一致性。

二、事務的并發問題

  1、臟讀:事務A讀取了事務B更新的數據,然后B回滾操作,那么A讀取到的數據是臟數據

  2、不可重復讀:事務 A 多次讀取同一數據,事務 B 在事務A多次讀取的過程中,對數據作了更新并提交,導致事務A多次讀取同一數據時,結果 不一致。

  3、幻讀:系統管理員A將數據庫中所有學生的成績從具體分數改為ABCDE等級,但是系統管理員B就在這個時候插入了一條具體分數的記錄,當系統管理員A改結束后發現還有一條記錄沒有改過來,就好像發生了幻覺一樣,這就叫幻讀。

  小結:不可重復讀的和幻讀很容易混淆,不可重復讀側重于修改,幻讀側重于新增或刪除。解決不可重復讀的問題只需鎖住滿足條件的行,解決幻讀需要鎖表

MySQL四種事務隔離級別詳解

三、MySQL事務隔離級別

mysql默認的事務隔離級別為repeatable-read

MySQL四種事務隔離級別詳解

四、用例子說明各個隔離級別的情況

1、讀未提交:

(1)打開一個客戶端A,并設置當前事務模式為read uncommitted(未提交讀),查詢表account的初始值:

MySQL四種事務隔離級別詳解

(2)在客戶端A的事務提交之前,打開另一個客戶端B,更新表account:

MySQL四種事務隔離級別詳解

(3)這時,雖然客戶端B的事務還沒提交,但是客戶端A就可以查詢到B已經更新的數據:

MySQL四種事務隔離級別詳解

(4)一旦客戶端B的事務因為某種原因回滾,所有的操作都將會被撤銷,那客戶端A查詢到的數據其實就是臟數據:

MySQL四種事務隔離級別詳解

(5)在客戶端A執行更新語句update account set balance = balance - 50 where id =1,lilei的balance沒有變成350,居然是400,是不是很奇怪,數據的一致性沒問啊,如果你這么想就太天真 了,在應用程序中,我們會用400-50=350,并不知道其他會話回滾了,要想解決這個問題可以采用讀已提交的隔離級別

MySQL四種事務隔離級別詳解

2、讀已提交

(1)打開一個客戶端A,并設置當前事務模式為read committed(未提交讀),查詢表account的初始值:

MySQL四種事務隔離級別詳解

(2)在客戶端A的事務提交之前,打開另一個客戶端B,更新表account:

MySQL四種事務隔離級別詳解

(3)這時,客戶端B的事務還沒提交,客戶端A不能查詢到B已經更新的數據,解決了臟讀問題:

MySQL四種事務隔離級別詳解

(4)客戶端B的事務提交

MySQL四種事務隔離級別詳解

(5)客戶端A執行與上一步相同的查詢,結果與上一步不一致,即產生了不可重復讀的問題,在應用程序中,假設我們處于客戶端A的會話,查詢到lilei的balance為450,但是其他事務將lilei的balance值改為400,我們并不知道,如果用450這個值去做其他操作,是有問題的,不過這個概率真的很小哦,要想避免這個問題,可以采用可重復讀的隔離級別

MySQL四種事務隔離級別詳解

3、可重復讀

(1)打開一個客戶端A,并設置當前事務模式為repeatable read,查詢表account的初始值:

MySQL四種事務隔離級別詳解

(2)在客戶端A的事務提交之前,打開另一個客戶端B,更新表account并提交,客戶端B的事務居然可以修改客戶端A事務查詢到的行,也就是mysql的可重復讀不會鎖住事務查詢到的行,這一點出乎我的意料,sql標準中事務隔離級別為可重復讀時,讀寫操作要鎖行的,mysql居然沒有鎖,我了個去。在應用程序中要注意給行加鎖,不然你會以步驟(1)中lilei的balance為400作為中間值去做其他操作

MySQL四種事務隔離級別詳解

(3)在客戶端A執行步驟(1)的查詢:

MySQL四種事務隔離級別詳解

(4)執行步驟(1),lilei的balance仍然是400與步驟(1)查詢結果一致,沒有出現不可重復讀的 問題;接著執行update balance = balance - 50 where id = 1,balance沒有變成400-50=350,lilei的balance值用的是步驟(2)中的350來算的,所以是300,數據的一致性倒是沒有被破壞,這個有點神奇,也許是mysql的特色吧

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
mysql> select * from account;
+------+--------+---------+
| id | name | balance |
+------+--------+---------+
| 1 | lilei |  400 |
| 2 | hanmei | 16000 |
| 3 | lucy | 2400 |
+------+--------+---------+
rows in set (0.00 sec)
 
mysql> update account set balance = balance - 50 where id = 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
 
mysql> select * from account;
+------+--------+---------+
| id | name | balance |
+------+--------+---------+
| 1 | lilei |  300 |
| 2 | hanmei | 16000 |
| 3 | lucy | 2400 |
+------+--------+---------+
rows in set (0.00 sec)

(5) 在客戶端A開啟事務,查詢表account的初始值

?
1
2
3
4
5
6
7
8
9
10
11
12
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
 
mysql> select * from account;
+------+--------+---------+
| id | name | balance |
+------+--------+---------+
| 1 | lilei | 300 |
| 2 | hanmei | 16000 |
| 3 | lucy | 2400 |
+------+--------+---------+
rows in set (0.00 sec)

(6)在客戶端B開啟事務,新增一條數據,其中balance字段值為600,并提交

?
1
2
3
4
5
6
7
8
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
 
mysql> insert into account values(4,'lily',600);
Query OK, 1 row affected (0.00 sec)
 
mysql> commit;
Query OK, 0 rows affected (0.01 sec)

(7) 在客戶端A計算balance之和,值為300+16000+2400=18700,沒有把客戶端B的值算進去,客戶端A提交后再計算balance之和,居然變成了19300,這是因為把客戶端B的600算進去了,站在客戶的角度,客戶是看不到客戶端B的,它會覺得是天下掉餡餅了,多了600塊,這就是幻讀,站在開發者的角度,數據的 一致性并沒有破壞。但是在應用程序中,我們得代碼可能會把18700提交給用戶了,如果你一定要避免這情況小概率狀況的發生,那么就要采取下面要介紹的事務隔離級別“串行化”

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
mysql> select sum(balance) from account;
+--------------+
| sum(balance) |
+--------------+
| 18700 |
+--------------+
1 row in set (0.00 sec)
 
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
 
mysql> select sum(balance) from account;
+--------------+
| sum(balance) |
+--------------+
| 19300 |
+--------------+
1 row in set (0.00 sec)

4.串行化

(1)打開一個客戶端A,并設置當前事務模式為serializable,查詢表account的初始值:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mysql> set session transaction isolation level serializable;
Query OK, 0 rows affected (0.00 sec)
 
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
 
mysql> select * from account;
+------+--------+---------+
| id | name | balance |
+------+--------+---------+
| 1 | lilei | 10000 |
| 2 | hanmei | 10000 |
| 3 | lucy | 10000 |
| 4 | lily | 10000 |
+------+--------+---------+
rows in set (0.00 sec)

(2)打開一個客戶端B,并設置當前事務模式為serializable,插入一條記錄報錯,表被鎖了插入失敗,mysql中事務隔離級別為serializable時會鎖表,因此不會出現幻讀的情況,這種隔離級別并發性極低,往往一個事務霸占了一張表,其他成千上萬個事務只有干瞪眼,得等他用完提交才可以使用,開發中很少會用到。

?
1
2
3
4
5
6
7
8
mysql> set session transaction isolation level serializable;
Query OK, 0 rows affected (0.00 sec)
 
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
 
mysql> insert into account values(5,'tom',0);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

補充: 

1、SQL規范所規定的標準,不同的數據庫具體的實現可能會有些差異

2、mysql中默認事務隔離級別是可重復讀時并不會鎖住讀取到的行

3、事務隔離級別為串行化時,讀取數據會鎖住整張表

4、閱讀此文時,如果站在開發者的角度,也許會覺得不可重復讀和幻讀,在邏輯上并沒有什么問題,最終數據仍然是一致的,但是站在用戶的角度,他們通常只能看到一個事務(只能看到客戶端A,不知道客戶端B這個臥底的存在),而不會考慮事務并發執行的現象,一旦出現同一數據多次讀取結果不同,或者憑空出現新記錄,他們可能會產生疑慮,這是用戶體驗的問題。

5.事務在mysql中執行時,最終的結果不會出現數據的一致性的問題,因為在一個事務中,mysql執行某個操作未必會使用前一個操作的中間結果,它會根據其他并發事務的實際情況采來處理,看起來不合邏輯,但是保證了數據的一致性 ;但是事務在應用程序中執行時,一個操作的結果會被下一個操作用到,并進行其他的計算。這是我們得小心,可重復讀的時候應該鎖行,串行化時 要鎖表,不然會破壞數據的一致性。

6、事務在mysql中執行時,mysql會根據各個事務的實際情況綜合處理,導致數據的一致性沒有被破壞,但是應用程序時按照邏輯套路來出牌,并沒有mysql聰明,難免會出現數據的一致性問題。

7、隔離級別越高,越能保證數據的完整性和一致性,但是對并發性能的影響也越大,魚和熊掌不可兼得啊。對于多數應用程序,可以優先考慮把數據庫系統的隔離級別設為Read Committed,它能夠避免臟讀取,而且具有較好的并發性能。盡管它會導致不可重復讀、幻讀這些并發問題,在可能出現這類問題的個別場合,可以由應用程序采用悲觀鎖或樂觀鎖來控制。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 日韩欧美在线视频 | 亚洲视频一区二区 | 亚洲免费视频在线观看 | 韩日中文字幕 | 亚洲天堂中文字幕在线观看 | 天天干在线影院 | 在线观看成人小视频 | 亚洲精品国产成人 | 欧美日韩亚洲一区二区 | 色综合色综合网色综合 | 亚洲综合在线播放 | 国外精品久久久蜜桃免费全文阅读 | 亚洲影视在线 | 在线观看一区 | 四虎影院最新地址 | 日日精品| 黄色网页在线观看 | 日韩视频免费在线观看 | 国产毛片久久久 | 1000部精品久久久久久久久 | 亚洲理论电影在线观看 | www.伊人| 4虎tv| 在线日韩欧美 | 黄色在线观看视频 | 在线观看亚洲 | 一本大道久久a久久精二百 国产欧美视频一区二区 | 亚洲国产高清在线 | 亚洲一级片av | 成人免费av电影 | 亚洲精品免费在线观看视频 | 精品国偷自产国产一区 | 中文字幕一区二区在线观看 | 亚洲欧美日韩在线 | 天天操天天插 | 亚洲精品视频在线免费播放 | 国产成人精品久久二区二区 | 韩日中文字幕 | 成人欧美一区二区三区在线播放 | 欧美黄视频 | 九九只有精品 |