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

跑了四個實驗,實戰講解 MySQL的行鎖、間隙鎖...

數據庫 MySQL
今天跟大家聊一聊MySQL的事務隔離,并通過一些實驗做了些總結。光說不練,假把式,沒有經過實踐就沒有話語權。

[[440226]]

大家好,我是Tom哥~

今天跟大家聊一聊MySQL的事務隔離,并通過一些實驗做了些總結。光說不練,假把式,沒有經過實踐就沒有話語權。

我們都知道數據庫有四種隔離級別,分別是:

  • 讀未提交(READ UNCOMMITTED)
  • 讀已提交 (READ COMMITTED)
  • 可重復讀 (REPEATABLE READ)
  • 串行化 (SERIALIZABLE)

實驗前的準備工作

1、基礎環境

當前的數據庫版本

  1. mysql> select version(); 
  2. +-----------+ 
  3. | version() | 
  4. +-----------+ 
  5. | 8.0.27    | 
  6. +-----------+ 
  7. 1 row in set (0.00 sec) 

當前的事務隔離級別

  1. mysql> show variables like 'transaction_isolation'
  2. +-----------------------+-----------------+ 
  3. | Variable_name         | Value           | 
  4. +-----------------------+-----------------+ 
  5. | transaction_isolation | REPEATABLE-READ | 
  6. +-----------------------+-----------------+ 
  7. 1 row in set (0.00 sec) 

2、創建個人收支表,并對 income 字段創建索引,expend字段沒有索引

  1. CREATE TABLE `person` ( 
  2.   `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主鍵'
  3.   `income` bigint(20) NOT NULL COMMENT '收入'
  4.   `expend` bigint(20) NOT NULL COMMENT '支出'
  5.   PRIMARY KEY (`id`), 
  6.   KEY `idx_income` (`income`) 
  7. ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='個人收支表'

3、初始化表數據,插入5條記錄

  1. insert into person values(100,1000,1000); 
  2. insert into person values(200,2000,2000); 
  3. insert into person values(300,3000,3000); 
  4. insert into person values(400,4000,4000); 
  5. insert into person values(500,5000,5000); 

實驗一:(事務A、B的條件字段沒有索引)

實驗過程:

為了便于描述,我們定義時間軸坐標,用T1、T2、T3... 表示當前時刻。

T1:

事務A開啟事務,并執行 select * from person where expend=4000 for update;

由于 expend 字段沒有索引,需要掃描全表。此時加的鎖是所有記錄的行鎖和它們之間的間隙鎖,也稱為 next-key lock,前開后閉區間。分別是 (-∞,100]、(100,200]、(200,300]、(300,400]、(400,500]、(500, +supremum]

T2:

事務B開啟事務,執行插入語句 insert into person values(401,4001,4001); 此時一直被阻塞住,因為并沒有獲得鎖。

面的這種情況,有兩種選擇:一種等到事務A結束(提交或回滾);另一種等事務鎖超時。

接著這個話題,我們稍微擴展介紹下鎖超時:

MySQL數據庫采用InnoDB模式,默認參數:innodb_lock_wait_timeout設置鎖等待的時間是50s,一旦數據庫鎖超過這個時間就會報錯。

  1. ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction 

當然,我們也可以通過命令來查看、修改這個超時時間

  1. # 查看超時時間 
  2. SHOW GLOBAL VARIABLES LIKE 'innodb_lock_wait_timeout'
  3.  
  4. # 修改時間 
  5. SET GLOBAL innodb_lock_wait_timeout=120; 

T3:

事務A ,執行 commit 操作, 提交事務

T4:

事務B,插入一條記錄,insert into person values(401,4001,4001); 操作成功。

此時 select * from person; 可以看到新插入的記錄

實驗二:(事務A、B的條件字段有創建索引)

T1:

事務A,開啟事務,并執行 select * from person where income=3000 for update,命中記錄且 income 有索引,此時的加鎖區間是 income=3000 的行記錄以及與下一個值4000之間的空隙(行鎖+間隙鎖),也就是[3000,4000]

T2:

事務B,開始事務,執行 insert into person values(301,3001,3001); 沒有搶到鎖,線程被阻塞住,直到事務A提交事務并釋放鎖。

實驗三:(自動識別死鎖)

特別說明:

T3:事務A執行insert操作,被事務B的鎖攔截住了

T4:同理,事務B執行insert操作,被事務A攔截了,這里被系統自動檢測到,拋出 ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction 。將事務B持有的鎖釋放掉,并重啟事務。

T5:事務A在T3時刻的insert可以繼續操作

實驗四:(更新記錄鎖保護)

1、事務A在執行后 update person set income=111 where income=3000; 開啟了鎖保護

2、這時,事務B再執行 insert into person values(307,3000,3000) 或者 update person set income=3000 where id=100,都會重新去搶奪鎖,從而保證安全。

知識小結

1、對于事務,binlog 日志是在 commit 提交時才生成的

2、行鎖與間隙鎖有很大區別。

行鎖:如果事務A對 id=1 添加行鎖,事務B則無法對 id=1 添加行鎖

間隙鎖:如果 select .. from 表名 where d=6 for updata,事務A 和 事務 B 都可以對(5,12)添加間隙鎖。間隙鎖是開區間。

3、行鎖和間隙鎖合稱 next-key lock,每個 next-key lock 是前開后閉區間。

4、只有在可重復讀的隔離級別下,才會有間隙鎖

5、讀提交級別沒有間隙鎖,只有行鎖,但是如何保證一個間隙操作產生的 binlog 對主從數據同步產生的影響呢?我們需要把 binlog 的格式設置為 row。

其本質就是將模糊操作改成了針對具體的主鍵id行操作

  1. # 初始語句 
  2. delete from order where c = 10 
  3.  
  4. # 轉換后語句 
  5. delete from order where id = 10 

6、大部分公司的數據庫的隔離級別都是讀提交隔離級別加 binlog_format=row 的組合

7、 大多數數據庫的默認級別就是讀提交(Read committed),比如Sql Server 、 Oracle。MySQL的默認級別是 可重復讀(Repeatable Read )

本文轉載自微信公眾號「微觀技術」

 

責任編輯:姜華 來源: 微觀技術
相關推薦

2023-11-06 08:35:08

表鎖行鎖間隙鎖

2025-06-04 02:55:00

MySQL意向鎖記錄鎖

2020-10-20 13:50:47

MySQL數據庫

2023-12-06 07:33:20

MySQL鎖事間隙鎖

2022-10-24 08:02:14

MySQL索引類型

2013-12-19 13:25:40

InnoDB數據庫

2024-11-29 07:38:12

MySQL數據庫

2024-01-16 12:19:08

MySQL重要機制高并發

2018-07-31 10:10:06

MySQLInnoDB死鎖

2022-04-29 11:39:28

MySQL幻讀Gap Lock

2020-07-02 08:22:56

MySQL間隙鎖過行鎖

2024-05-13 12:44:00

InnodbMySQL行級鎖

2010-05-24 12:50:59

MySQL表級鎖

2025-02-10 09:58:48

2019-11-15 08:46:16

MySQLMVCC表讀鎖

2024-03-04 00:01:00

鎖表鎖行MySQL

2020-02-06 10:02:45

MySQL數據庫全局鎖

2022-10-24 00:33:59

MySQL全局鎖行級鎖

2021-10-26 00:07:35

TCP連接python

2022-07-20 08:06:57

MySQL表鎖Innodb
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产日韩一区二区三区 | 日韩亚洲一区二区 | 国产激情| 欧美美女爱爱视频 | 羞羞视频在线观看 | 美国十次成人欧美色导视频 | 99久久国产免费 | 精品国产免费一区二区三区演员表 | 久久国产精品99久久久久久丝袜 | 91在线视频一区 | 日日草夜夜草 | 色噜噜色综合 | 国产精品视频网址 | 日日天天 | 欧美在线国产精品 | 国产一区二区在线看 | 天天成人综合网 | 给我免费的视频在线观看 | 欧美日韩亚洲国产 | 国产欧美综合在线 | 亚洲性在线 | 97精品超碰一区二区三区 | 精品国产乱码久久久久久闺蜜 | 日韩欧美高清 | 国产乱码精品1区2区3区 | 亚洲一区二区久久 | 韩国久久精品 | 国产精品久久久久久久岛一牛影视 | 精品一区在线看 | 午夜影院网站 | 人和拘一级毛片c | 在线免费观看成年人视频 | 亚洲成人免费观看 | 欧洲亚洲视频 | 免费国产黄网站在线观看视频 | 在线观看成人免费视频 | 美女久久视频 | 一级欧美| av国产精品 | 午夜丰满寂寞少妇精品 | 97精品国产|