成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

實例分析MySQL下的四種事務隔離級別

數據庫 MySQL
數據庫事務有四種隔離級別,本文我們就通過具體的實例來解釋四個隔離級別。

實例分析MySQL下的四種事務隔離級別

數據庫事務有四種隔離級別:

  • 未提交讀(Read Uncommitted):允許臟讀,也就是可能讀取到其他會話中未提交事務修改的數據。
  • 提交讀(Read Committed):只能讀取到已經提交的數據,Oracle等多數數據庫默認都是該級別。
  • 可重復讀(Repeated Read):可重復讀。在同一個事務內的查詢都是事務開始時刻一致的,InnoDB默認級別。在SQL標準中,該隔離級別消除了不可重復讀,但是還存在幻讀。
  • 串行讀(Serializable):完全串行化的讀,每次讀都需要獲得表級共享鎖,讀寫相互都會阻塞。

上面這樣的教科書式定義***次接觸事務隔離概念的朋友看了可能會一臉懵逼,下面我們就通過具體的實例來解釋四個隔離級別。

首先我們創建一個user表:

  1. CREATE TABLE user ( 
  2.     `id` int(11) NOT NULL AUTO_INCREMENT, 
  3.     `namevarchar(255) NOT NULL
  4.     PRIMARY KEY (`id`), 
  5.     UNIQUE `uniq_name` USING BTREE (name
  6. ) ENGINE=`InnoDB` AUTO_INCREMENT=10 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; 

 

讀未提交隔離級別

我們先將事務的隔離級別設置為read committed:

  1. mysql> set session transaction isolation level read uncommitted
  2. Query OK, 0 rows affected (0.00 sec) 
  3.  
  4. mysql> select @@session.tx_isolation; 
  5. +------------------------+ 
  6. | @@session.tx_isolation | 
  7. +------------------------+ 
  8. READ-UNCOMMITTED       | 
  9. +------------------------+ 
  10. 1 row in set (0.00 sec) 

 

在下面我們開了兩個終端分別用來模擬事務一和事務二,p.s: 操作一和操作二的意思是按照時間順序來執行的。

事務1

  1. mysql> start transaction; # 操作1 
  2.  
  3. Query OK, 0 rows affected (0.00 sec) 
  4.  
  5. mysql> insert into user(namevalues('ziwenxie'); # 操作3 
  6.  
  7. Query OK, 1 row affected (0.05 sec) 

 

事務2

  1. mysql> start transaction; # 操作2 
  2.  
  3. Query OK, 0 rows affected (0.00 sec) 
  4.  
  5. mysql> select * from user; # 操作4 
  6.  
  7. +----+----------+ 
  8.  
  9. | id | name | 
  10.  
  11. +----+----------+ 
  12.  
  13. | 10 | ziwenxie | 
  14.  
  15. +----+----------+ 
  16.  
  17. 1 row in set (0.00 sec) 

 

從上面的執行結果可以和清晰的看出來,在read uncommited級別下面我們在事務一中可能會讀取到事務二中沒有commit的數據,這就是臟讀。

讀提交隔離級別

通過設置隔離級別為committed可以解決上面的臟讀問題。

  1. mysql> set session transaction isolation level read committed

事務一

  1. mysql> start transaction; # 操作一 
  2.  
  3. Query OK, 0 rows affected (0.00 sec) 
  4.  
  5. mysql> select * from user; # 操作三 
  6.  
  7. +----+----------+ 
  8.  
  9. | id | name | 
  10.  
  11. +----+----------+ 
  12.  
  13. | 10 | ziwenxie | 
  14.  
  15. +----+----------+ 
  16.  
  17. 1 row in set (0.00 sec) 
  18.  
  19. mysql> select * from user; # 操作五,操作四的修改并沒有影響到事務一 
  20.  
  21. +----+----------+ 
  22.  
  23. | id | name | 
  24.  
  25. +----+----------+ 
  26.  
  27. | 10 | ziwenxie | 
  28.  
  29. +----+----------+ 
  30.  
  31. 1 row in set (0.00 sec) 
  32.  
  33. mysql> select * from user; # 操作七 
  34.  
  35. +----+------+ 
  36.  
  37. | id | name | 
  38.  
  39. +----+------+ 
  40.  
  41. | 10 | lisi | 
  42.  
  43. +----+------+ 
  44.  
  45. 1 row in set (0.00 sec) 
  46.  
  47. mysql> commit; # 操作八 
  48.  
  49. Query OK, 0 rows affected (0.00 sec) 

 

事務二

  1. mysql> start transaction; # 操作二 
  2.  
  3. Query OK, 0 rows affected (0.00 sec) 
  4.  
  5. mysql> update user set name='lisi' where id=10; # 操作四 
  6.  
  7. Query OK, 1 row affected (0.06 sec) 
  8.  
  9. Rows matched: 1 Changed: 1 Warnings: 0 
  10.  
  11. mysql> commit; # 操作六 
  12.  
  13. Query OK, 0 rows affected (0.08 sec) 

 

雖然臟讀的問題解決了,但是注意在事務一的操作七中,事務二在操作六commit后會造成事務一在同一個transaction中兩次讀取到的數據不同,這就是不可重復讀問題,使用第三個事務隔離級別repeatable read可以解決這個問題。

可重復讀隔離級別

MySQL的Innodb存儲引擎默認的事務隔離級別就是可重復讀隔離級別,所以我們不用進行多余的設置。

事務一

  1. mysql> start tansactoin; # 操作一 
  2.  
  3. mysql> select * from user; # 操作五 
  4.  
  5. +----+----------+ 
  6.  
  7. | id | name | 
  8.  
  9. +----+----------+ 
  10.  
  11. | 10 | ziwenxie | 
  12.  
  13. +----+----------+ 
  14.  
  15. 1 row in set (0.00 sec) 
  16.  
  17. mysql> commit; # 操作六 
  18.  
  19. Query OK, 0 rows affected (0.00 sec) 
  20.  
  21. mysql> select * from user; # 操作七 
  22.  
  23. +----+------+ 
  24.  
  25. | id | name | 
  26.  
  27. +----+------+ 
  28.  
  29. | 10 | lisi | 
  30.  
  31. +----+------+ 
  32.  
  33. 1 row in set (0.00 sec) 

 

事務二

  1. mysql> start tansactoin; # 操作二 
  2.  
  3. mysql> update user set name='lisi' where id=10; # 操作三 
  4.  
  5. Query OK, 1 row affected (0.00 sec) 
  6.  
  7. Rows matched: 1 Changed: 1 Warnings: 0 
  8.  
  9. mysql> commit; # 操作四 

 

在事務一的操作五中我們并沒有讀取到事務二在操作三中的update,只有在commit之后才能讀到更新后的數據。

Innodb解決了幻讀么

實際上RR級別是可能產生幻讀,InnoDB引擎官方稱中利用MVCC多版本并發控制解決了這個問題,下面我們驗證一下Innodb真的解決了幻讀了么?

為了方便展示,我修改了一下上面的user表:

  1. mysql> alter table user add salary int(11); 
  2.  
  3. Query OK, 0 rows affected (0.51 sec) 
  4.  
  5. Records: 0 Duplicates: 0 Warnings: 0 
  6.  
  7. mysql> delete from user
  8.  
  9. Query OK, 1 rows affected (0.07 sec) 
  10.  
  11. mysql> insert into user(name, salary) value('ziwenxie', 88888888); 
  12.  
  13. Query OK, 1 row affected (0.07 sec) 
  14.  
  15. mysql> select * from user
  16.  
  17. +----+----------+----------+ 
  18.  
  19. | id | name | salary | 
  20.  
  21. +----+----------+----------+ 
  22.  
  23. | 10 | ziwenxie | 88888888 | 
  24.  
  25. +----+----------+----------+ 
  26.  
  27. 1 row in set (0.00 sec) 

 

事務一

  1. mysql> start transaction; # 操作一 
  2.  
  3. Query OK, 0 rows affected (0.00 sec) 
  4.  
  5. mysql> update user set salary='4444'; # 操作六,竟然影響了兩行,不是說解決了幻讀么? 
  6.  
  7. Query OK, 2 rows affected (0.00 sec) 
  8.  
  9. Rows matched: 2 Changed: 2 Warnings: 0 
  10.  
  11. mysql> select * from user; # 操作七, Innodb并沒有完全解決幻讀 
  12.  
  13. +----+----------+--------+ 
  14.  
  15. | id | name | salary | 
  16.  
  17. +----+----------+--------+ 
  18.  
  19. | 10 | ziwenxie | 4444 | 
  20.  
  21. | 11 | zhangsan | 4444 | 
  22.  
  23. +----+----------+--------+ 
  24.  
  25. rows in set (0.00 sec) 
  26.  
  27. mysql> commit; # 操作八 
  28.  
  29. Query OK, 0 rows affected (0.04 sec) 

 

事務二

  1. mysql> start transaction; # 操作二 
  2.  
  3. Query OK, 0 rows affected (0.00 sec) 
  4.  
  5. mysql> insert into user(name, salary) value('zhangsan''666666'); # 操作四 
  6.  
  7. Query OK, 1 row affected (0.00 sec) 
  8.  
  9. mysql> commit; # 操作五 
  10.  
  11. Query OK, 0 rows affected (0.04 sec) 

 

從上面的例子可以看出,Innodb并沒有如官方所說解決幻讀,不過上面這樣的場景中也不是很常見不用過多的擔心。

串行化隔離級別

所有事務串行執行,***隔離級別,不會出現幻讀性能會很差,實際開發中很少使用到。 

責任編輯:龐桂玉 來源: segmentfault
相關推薦

2018-01-03 08:52:27

MySQL數據庫級別

2019-04-26 14:12:19

MySQL數據庫隔離級別

2018-12-19 16:46:38

MySQL事務隔離數據庫

2020-09-21 18:44:35

MySQL

2021-08-30 20:12:11

MySQL事務隔離

2021-08-04 13:19:42

MySQL 事務隔離

2021-07-26 10:28:13

MySQL事務隔離

2024-04-26 09:17:20

MySQL事務隔離

2012-02-29 09:44:54

MySQL

2022-06-29 11:01:05

MySQL事務隔離級別

2024-12-02 08:37:04

2020-04-07 09:21:45

MySQL數據庫SQL

2023-02-02 07:06:10

2025-01-13 13:12:54

2020-10-13 10:32:24

MySQL事務MVCC

2025-03-03 08:20:00

MySQL事務隔離數據庫

2009-06-29 17:54:47

Spring事務隔離

2010-11-19 16:13:06

oracle事務隔離級

2018-07-17 10:58:45

數據庫數據庫事務隔離級別

2020-06-24 07:49:13

Kubernetes場景網絡
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91成人精品视频 | 国产一区二区在线免费观看 | 成人在线精品 | 国产激情精品一区二区三区 | 99精品99 | 精品免费国产一区二区三区四区介绍 | 日韩午夜在线播放 | 91天堂网| 一区二区三区成人 | 国产免费人成xvideos视频 | 日日夜夜精品视频 | 三级视频在线观看电影 | 免费看黄视频网站 | 午夜网 | 久久精品视频一区二区三区 | 韩日一区二区三区 | 免费久久久 | a免费视频 | 午夜在线免费观看 | 国产在线精品一区二区 | 日韩在线精品 | 国产精品美女www爽爽爽视频 | 亚洲一区二区三区观看 | 国内精品视频一区二区三区 | 亚洲电影成人 | 伦理一区二区 | 在线观看www视频 | 中文字幕在线一区二区三区 | 久久爱综合 | 欧美一a一片一级一片 | 亚洲最大av网站 | 欧美一区二区三区久久精品视 | 国产精品高潮呻吟久久av野狼 | 国产一二区视频 | 精品自拍视频在线观看 | 五月天国产视频 | 中文字幕精品一区二区三区精品 | 精品欧美乱码久久久久久1区2区 | 久久久性| 婷婷在线免费 | 国产精品18久久久久久白浆动漫 |