在依賴事務的項目中,如果SQL語句設計不合理或者執行順序不合理,就容易引發死鎖。本文介紹一個因為Duplicate Key引發的死鎖
user
CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(64) NOT NULL, `age` int(11) DEFAULT NULL, PRIMARY KEY (`id`), #唯一索引 UNIQUE KEY `uk_name` (`name`)) ENGINE=InnoDB DEFAULT CHARSET=utf8
MySQL> select * FROM user;+----+------+------+| id | name | age |+----+------+------+| 1 | tenmao | NULL |+----+------+------+1 row in set (0.00 sec)
BEGIN;# Duplicate key(所以插入失敗)insert INTO user VALUES(null, 'tenmao', 3);# 此時再執行事務2的語句(會等待)# 插入失敗則更新update user SET age=3 WHERE name='tenmao';COMMIT;
# 單SQL事務(默認)update user SET age =3 WHERE name ='tenmao';
在事務1執行insert INTO user VALUES(null, 'tenmao', 3);
失敗后,執行事務2,事務2等待后,再繼續執行事務1,觸發死鎖。
mysql> BEGIN;Query OK, 0 rows affected (0.00 sec)mysql> insert INTO user VALUES(null, 'tenmao', 3);ERROR 1062 (23000): Duplicate entry 'tenmao' for key 'uk_name'mysql> update user SET age=3 WHERE name='tenmao';Query OK, 1 row affected (0.00 sec)Rows matched: 1 Changed: 1 Warnings: 0mysql> COMMIT;Query OK, 0 rows affected (0.01 sec)
mysql> update user SET age =3 WHERE name ='tenmao';ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
當事務2等待時,查看InnoDB鎖的情況,分別是INFORMATION_SCHEMA.INNODB_LOCKS, INFORMATION_SCHEMA.INNODB_LOCK_WAITS, INFORMATION_SCHEMA.INNODB_TRX
# 獲取鎖的情況mysql> select * FROM INFORMATION_SCHEMA.INNODB_LOCKS;+---------------+-------------+-----------+-----------+-----------------+------------+------------+-----------+----------+-----------+| lock_id | lock_trx_id | lock_mode | lock_type | lock_table | lock_index | lock_space | lock_page | lock_rec | lock_data |+---------------+-------------+-----------+-----------+-----------------+------------+------------+-----------+----------+-----------+| 50505:361:4:2 | 50505 | X | RECORD | `tenmao`.`user` | uk_name | 361 | 4 | 2 | 'tenmao' || 50504:361:4:2 | 50504 | S | RECORD | `tenmao`.`user` | uk_name | 361 | 4 | 2 | 'tenmao' |+---------------+-------------+-----------+-----------+-----------------+------------+------------+-----------+----------+-----------+2 rows in set, 1 warning (0.00 sec)# 查看鎖等待情況mysql> select * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;+-------------------+-------------------+-----------------+------------------+| requesting_trx_id | requested_lock_id | blocking_trx_id | blocking_lock_id |+-------------------+-------------------+-----------------+------------------+| 50505 | 50505:361:4:2 | 50504 | 50504:361:4:2 |+-------------------+-------------------+-----------------+------------------+1 row in set, 1 warning (0.00 sec)# 查看事務狀態mysql> select * FROM INFORMATION_SCHEMA.INNODB_TRXG*************************** 1. row *************************** trx_id: 50505 trx_state: LOCK WAIT trx_started: 2019-12-13 14:55:00 trx_requested_lock_id: 50505:361:4:2 trx_wait_started: 2019-12-13 14:59:49 trx_weight: 2 trx_mysql_thread_id: 2557 trx_query: update user set age =3 where name ='tenmao' trx_operation_state: starting index read trx_tables_in_use: 1 trx_tables_locked: 1 trx_lock_structs: 2 trx_lock_memory_bytes: 1136 trx_rows_locked: 3 trx_rows_modified: 0 trx_concurrency_tickets: 0 trx_isolation_level: REPEATABLE READ trx_unique_checks: 1 trx_foreign_key_checks: 1trx_last_foreign_key_error: NULL trx_adaptive_hash_latched: 0 trx_adaptive_hash_tenmaoeout: 0 trx_is_read_only: 0trx_autocommit_non_locking: 0*************************** 2. row *************************** trx_id: 50504 trx_state: RUNNING trx_started: 2019-12-13 14:54:25 trx_requested_lock_id: NULL trx_wait_started: NULL trx_weight: 4 trx_mysql_thread_id: 2556 trx_query: NULL trx_operation_state: NULL trx_tables_in_use: 0 trx_tables_locked: 1 trx_lock_structs: 4 trx_lock_memory_bytes: 1136 trx_rows_locked: 2 trx_rows_modified: 0 trx_concurrency_tickets: 0 trx_isolation_level: REPEATABLE READ trx_unique_checks: 1 trx_foreign_key_checks: 1trx_last_foreign_key_error: NULL trx_adaptive_hash_latched: 0 trx_adaptive_hash_tenmaoeout: 0 trx_is_read_only: 0trx_autocommit_non_locking: 02 rows in set (0.00 sec)
BEGIN;# Duplicate key(所以插入失敗)insert INTO user VALUES(null, 'tenmao', 3);# 此時因為重復鍵,事務拿到記錄的`S鎖`# 此時再執行事務2的語句(會等待)# 插入失敗則更新(獲取X鎖,但是因為事務2排在前面,需要事務2釋放`X鎖`,另一方面事務2也在等待事務1釋放`S鎖`,所以形成死鎖)update user SET age=3 WHERE name='tenmao';COMMIT;
# 單SQL事務(嘗試獲取X鎖,等待事務1釋放`S鎖`)update user SET age =3 WHERE name ='tenmao';
本文由 貴州做網站公司 整理發布,部分圖文來源于互聯網,如有侵權,請聯系我們刪除,謝謝!
網絡推廣與網站優化公司(網絡優化與推廣專家)作為數字營銷領域的核心服務提供方,其價值在于通過技術手段與策略規劃幫助企業提升線上曝光度、用戶轉化率及品牌影響力。這...
在當今數字化時代,公司網站已成為企業展示形象、傳遞信息和開展業務的重要平臺。然而,對于許多公司來說,網站建設的價格是一個關鍵考量因素。本文將圍繞“公司網站建設價...
在當今的數字化時代,企業網站已成為企業展示形象、吸引客戶和開展業務的重要平臺。然而,對于許多中小企業來說,高昂的網站建設費用可能會成為其發展的瓶頸。幸運的是,隨...
k515時刻表 k515列車上有多少座?k515運行狀態? K515列車是從吉林起點站到上?;疖囌镜目焖倭熊?。每天8點25分,33小時零8分到達終點站。每節普通硬座車廂有118個座位。硬臥車廂有60或66個座位和54個座位。每個小房間有6張床,每邊有中下三張床。每張床對應購買的票號,其他床號不能隨意占用。 k515次列車路線? K518/K515從吉林站到上海站共有29站,08:25出發,...
筆記本無線網卡一個月多少錢?筆記本聯通無線上網卡的收費是上網0.01元/KB,短信0.10元/條。無線網卡的數量有限。當用戶當月無線上網的數據流量達到15GB時,系統會自動關閉用戶數據功能,下月自動開啟,系統會提供短信流量提醒功能。上網費不區分本地和漫游,在國內任何3G網絡覆蓋區域(不含臺港澳)都是一個價。套餐按流量計費,計費單位為MB,不足1MB的部分為1MB。套餐不自動升級,超出套餐的流量按實...
明天鄭州有到遵義的火車票嗎?K507鄭州到遵義06:03出發07:28到達耗時25:25小時,第二天到達硬臥¥337.0硬座¥198.0。北京到遵義火車有幾班,時間是多少?北京到遵義一共1趟車?;疖囋谲囌景l車,到達車站,在車站發車,到達車站,在車站行駛,有硬座,軟座,軟臥,軟臥。始發站-終點站類型K507北京西遵義22 : 1609 : 30 35小時14分271-490 754北京西-遵義高速。...