Mysql并發時常見的死鎖及解決方法

使用數據庫時,有時會出現死鎖。對于實際應用來說,就是出現系統卡頓。

死鎖是指兩個或兩個以上的事務在執行過程中,因爭奪資源而造成的一種互相等待的現象。就是所謂的鎖資源請求產生了回路現象,即死循環,此時稱系統處于死鎖狀態或系統產生了死鎖。常見的報錯信息為“Deadlock found when trying to get lock...”。


上圖中,很明顯是右側的四輛汽車造成了死鎖。

死鎖發生以后,只有部分或完全回滾其中一個事務,才能打破死鎖。多數情況下只需要重新執行因死鎖回滾的事務即可。下面我們通過一個實例來了解死鎖是如何產生的。

例 1

為了方便讀者閱讀,操作之前我們先查詢 tb_student 表的數據和表結構。

mysql> SELECT * FROM tb_student;
+----+------+------+------+------+
| id | name | age  | sex  | num  |
+----+------+------+------+------+
|  1 | 張三 |   31 | 男   |    4 |
|  2 | 李四 |   28 | 男   |    4 |
|  3 | 王五 |   13 | 女   |    4 |
|  4 | 張四 |   13 | 女   |    4 |
|  5 | 王四 |   15 | 男   |    4 |
|  6 | 趙六 |   12 | 女   |    4 |
+----+------+------+------+------+
6 rows in set (0.01 sec)mysql> DESC tb_student;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(4)      | NO   | PRI | NULL    | auto_increment |
| name  | varchar(25) | NO   |     | NULL    |                |
| age   | int(11)     | YES  | MUL | NULL    |                |
| sex   | char(1)     | YES  |     | NULL    |                |
| num   | int(11)     | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

以下操作需要打開兩個會話窗口,即下面所提到的 A窗口和 B窗口。

在 A窗口中執行以下命令:

mysql> BEGIN;
mysql> UPDATE tb_student SET num=5 WHERE age=13;
Query OK, 2 rows affected (0.04 sec)
Rows matched: 2  Changed: 2  Warnings: 0

緊接著在 B窗口中執行以下命令。由于 age 是索引字段,與 A窗口中更新的是不同行的數據,所以這時不會出現鎖等待現象。

mysql> BEGIN;
mysql> UPDATE tb_student SET num=8 WHERE age=15;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

然后在 A窗口中,執行以下命令,這時就會出現鎖等待現象了。

mysql> UPDATE tb_student SET num=10 WHERE age=15;

最后在 B窗口中,執行以下命令,這時會出現相互等待資源的現象,也就是死鎖現象。

mysql> UPDATE tb_student SET num=12 WHERE age=13;
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

我們可以通過 SHOW ENGINE INNODB STATUS 命令查看死鎖的信息,運行結果如下(這里只展示了部分信息):

LATEST DETECTED DEADLOCK
------------------------
2020-08-24 16:22:23 0x3944
*** (1) TRANSACTION:
TRANSACTION 22656, ACTIVE 108 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 5 lock struct(s), heap size 1136, 6 row lock(s), undo log entries 2
MySQL thread id 33, OS thread handle 8808, query id 1689 localhost ::1 root updating
UPDATE tb_student SET num=10 WHERE age=15
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 197 page no 8 n bits 80 index index_age of table `test`.`tb_student` trx id 22656 lock_mode X waiting
Record lock, heap no 5 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 8000000f; asc     ;;
1: len 4; hex 80000005; asc     ;;
......

通過以上日志,我們就能確定造成死鎖的事務和 SQL 語句。

死鎖檢測

InnoDB 的并發寫操作會觸發死鎖,同時 InnoDB 也提供了死鎖檢測機制。通過設置 innodb_deadlock_detect 參數的值來控制是否打開死鎖檢測。

  • innodb_deadlock_detect = ON :默認值,打開死鎖檢測。數據庫發生死鎖時,系統會自動回滾其中的某一個事務,讓其它事務可以繼續執行。
  • innodb_deadlock_detect = OFF:關閉死鎖檢測。發生死鎖時,系統會用鎖等待來處理。


鎖等待是指在事務過程中產生的鎖,其它事務需要等待上一個事務釋放鎖,才能占用該資源。如果該事務一直不釋放,就需要持續等待下去,直到超過了鎖等待時間。當超過鎖等待允許的最大時間,就會出現死鎖,然后當前事務執行失敗,自動執行回滾操作。

MySQL 通過 innodb_lock_wait_timeout 參數控制鎖等待的時間,單位是秒。

mysql> SHOW VARIABLES LIKE '%innodb_lock_wait%';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| innodb_lock_wait_timeout | 120   |
+--------------------------+-------+
1 row in set, 1 warning (0.02 sec)

在實際應用中,我們要盡量防止鎖等待現象的發生,下面介紹幾種避免死鎖的方法:

  1. 如果不同程序會并發存取多個表,或者涉及多行記錄時,盡量約定以相同的順序訪問表,這樣可以大大降低死鎖的發生。
  2. 業務中要及時提交或者回滾事務,可減少死鎖產生的概率。
  3. 在同一個事務中,盡可能做到一次鎖定所需要的所有資源,減少死鎖產生概率。
  4. 對于非常容易產生死鎖的業務部分,可以嘗試使用升級鎖粒度,通過表鎖定來減少死鎖產生的概率(表級鎖不會產生死鎖)。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/166773.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/166773.shtml
英文地址,請注明出處:http://en.pswp.cn/news/166773.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

星河創新,開拓新紀!2023“星河產業應用創新獎”報名全面開啟!

科技的浪潮洶涌而至,人工智能正悄無聲息地滲透進我們生活的每一個角落,成為推動社會奔騰向前的強大引擎。 隨著大模型時代到來,更多的創新者涌現出來,他們正積極探索AI與實體的深度融合,解決行業難題,開拓…

算法的奧秘:種類、特性及應用詳解(算法導論筆記1)

算法,是計算機科學領域的靈魂,是解決問題的重要工具。在算法的世界里,有著各種各樣的種類和特性。今天,我將帶各位踏上一段探索算法種類的旅程,分享一些常見的算法種類,并給出相應的實踐和案例分析。希望通…

c# 微信小程序支付,訂單錄入發貨

微信改動,大家一起改,來吧 private string GetAccessToken(string openid){string AppID "";string AppSecret "";string url "https://api.weixin.qq.com/cgi-bin/token?grant_typeclient_credential&appid"AppI…

華納云:Linux每天自動備份mysql數據庫怎么實現

在 Linux 系統中,你可以使用 cron 任務來定期執行 MySQL 數據庫備份。以下是一個簡單的步驟,演示如何設置每天自動備份 MySQL 數據庫: 創建備份腳本: 創建一個 Shell 腳本,其中包含備份 MySQL 數據庫的命令。假設腳本名…

【目標檢測】保姆級別教程從零開始實現基于Yolov8的一次性筷子計數

前言 一,環境配置 一,虛擬環境創建 二,安裝資源包 前言 最近事情比較少,無意間刷到群聊里分享的基于百度飛漿平臺的一次性筷子檢測,感覺很有意思,恰巧自己最近在學習Yolov8,于是看看能不能復…

前端JS數據時間排序

一、sort()方法 var data [ { name:‘1’, time:‘2019-04-26 10:53:19’ }, { name:‘2’, time:‘2019-04-26 10:51:19’ },{ name:‘3’, time:‘2019-04-26 11:04:32’ },{ name:‘4’, time:‘2019-04-26 11:05:32’ } ] data.sort(function(a,b){ return a.time < b…

js進階筆記之作用域

目錄 全局作用域 局部作用域 函數作用域 塊作用域 作用域鏈 閉包 垃圾回收機制 作用域&#xff08;scope&#xff09;規定了變量能夠被訪問的“范圍”&#xff0c;離開了這個“范圍”變量便不能被訪問&#xff0c;作用域分為全局作用域和局部作用域。 全局作用域 <…

【Go語言從入門到實戰】反射編程、Unsafe篇

反射編程 reflect.TypeOf vs reflect.ValueOf func TestTypeAndValue(t *testing.T) {var a int64 10t.Log(reflect.TypeOf(a), reflect.ValueOf(a))t.Log(reflect.ValueOf(a).Type()) }判斷類型 - Kind() 當我們需要對反射回來的類型做判斷時&#xff0c;Go 語言內置了一個…

【23真題】最簡單的211!均分141分!

今天分享的是23年河海大學863的信號與系統試題及解析。 我猜測是由于23年太簡單&#xff0c;均分都141分&#xff0c;導致24考研臨時新增一門數字信號處理&#xff01;今年考研的同學趕不上這么簡單的專業課啦&#xff01; 本套試卷難度分析&#xff1a;平均分為102和141分&a…

ECharts與DataV:數據可視化的得力助手

文章目錄 引言一、ECharts簡介優勢&#xff1a;劣勢&#xff1a; 二、DataV簡介優勢&#xff1a;劣勢&#xff1a; 三、ECharts與DataV的聯系四、區別與選擇五、如何選擇根據需求選擇技術棧考慮預算和商業考慮 結論我是將軍&#xff0c;我一直都在&#xff0c;。&#xff01; 引…

LeetCode題解:13. 羅馬數字轉整數,哈希表,JavaScript,詳細注釋

原題鏈接&#xff1a;13. 羅馬數字轉整數 解題思路&#xff1a; 本題涉及到的羅馬數字都是唯一的&#xff0c;因此可以創建一個哈希表&#xff0c;存儲羅馬數字和整數的對應關系。遍歷s&#xff0c;分別截取從i開始的2位和1位字符串&#xff0c;查看其在哈希表中的羅馬數字對…

pytest調用其他測試用例方法

pytest調用其他測試用例方法 一. 第一種方法&#xff0c;測試用例前置pytest.fixture() def test1():print("我是用例一") pytest.fixture(test1) def test2():print("我是用例二")二.第二種方法,如果不是同一文件中測試用例調用或者同一py文件中 def t…

3.10-容器的操作

這一節講解一下對于container我們可以進行哪些操作&#xff1f; 可以使用以下命令來停止正在運行的Docker容器&#xff1a; docker container stop <CONTAINER ID> 關于運行中的容器&#xff0c;我們可以進行的操作&#xff1a; 第一個是docker exec命令&#xff0c;這個…

NLP實踐——LLM生成過程中防止重復循環

NLP實踐——LLM生成過程中防止重復 1. 準備工作2. 問題分析3. 創建processor3.1 防止重復生成的processor3.2 防止數字無規則循環的processor 4. 使用 本文介紹如何使用LogitsProcessor避免大模型在生成過程中出現重復的問題。 1. 準備工作 首先實例化一個大模型&#xff0c;…

實時語音克隆:5 秒內生成任意文本的語音 | 開源日報 No.84

CorentinJ/Real-Time-Voice-Cloning Stars: 43.3k License: NOASSERTION 這個開源項目是一個實時語音克隆工具&#xff0c;可以在5秒內復制一種聲音&#xff0c;并生成任意文本的語音。 該項目的主要功能包括&#xff1a; 從幾秒鐘的錄音中創建聲紋模型根據給定文本使用參考…

數字化轉型沒錢?沒人?沒IT?低代碼平臺輕松幫你搞定

隨著數字技術的不斷滲透&#xff0c;數字化已經不僅僅是一個趨勢&#xff0c;而是深入人心的日常生活部分。在這樣的時代背景下&#xff0c;企業面臨的挑戰也愈發嚴峻&#xff1a;如何不斷創新&#xff0c;滿足用戶日益增長的業務需求&#xff1f; 傳統的開發方式&#xff0c;隨…

基于單片機設計的大氣氣壓檢測裝置(STC89C52+BMP180實現)

一、前言 本項目設計一個大氣氣壓檢測裝置&#xff0c;該裝置以單片機為基礎&#xff0c;采用STC89C52作為核心控制芯片&#xff0c;結合BMP180模塊作為氣壓傳感器。大氣氣壓&#xff0c;也就是由氣體重力在大氣層中產生的壓力&#xff0c;其變化與天氣預報、氣象觀測以及高度…

江蘇某市人民醫院實現IT基礎資源統一監控

一、背景介紹 江蘇某市人民醫院是一家擁有豐富醫療資源和龐大患者群體的醫療機構。隨著醫療業務的不斷發展&#xff0c;其IT系統的規模和復雜性也不斷增加&#xff0c;涉及各類IT資源&#xff0c;包括服務器、網絡設備、數據庫、應用軟件等。為了提高IT系統的可靠性和穩定性&am…

11.7統一功能處理

一.登錄攔截器 1.實現一個普通的類,實現HeadlerInterceptor接口,重寫preHeadler方法. 2.將攔截器添加到配置中,并設定攔截規則. 二.訪問前綴添加 方法1: 方法2:properties 三.統一異常處理 以上返回的是空指針異常,如果是別的異常就不會識別,建議加上最終異常 . 四.統一數據格…

英語學習軟件 Eudic歐路詞典 mac中文版介紹說明

歐路詞典 mac (Eudic) 是一個功能強大的英語學習工具&#xff0c;它包含了豐富的英語詞匯、短語和例句&#xff0c;并提供了發音、例句朗讀、單詞筆記等功能。 Eudic歐路詞典 mac 軟件介紹 多語種支持&#xff1a;歐路詞典支持多種語言&#xff0c;包括英語、中文、日語、法語…