濮阳杆衣贸易有限公司

主頁 > 知識庫 > 5分鐘快速了解數(shù)據(jù)庫死鎖產(chǎn)生的場景和解決方法

5分鐘快速了解數(shù)據(jù)庫死鎖產(chǎn)生的場景和解決方法

熱門標(biāo)簽:400電話申請?jiān)趺纯?/a> hbuilder地圖標(biāo)注 天音通信電話機(jī)器人 杭州400電話如何申請的 高德地圖標(biāo)注商家在哪 江西南昌百應(yīng)電話機(jī)器人 機(jī)器人電話機(jī)創(chuàng)意繪畫 隨州營銷電話機(jī)器人怎么樣 400電話從哪里申請濱州

前言

加鎖(Locking)是數(shù)據(jù)庫在并發(fā)訪問時(shí)保證數(shù)據(jù)一致性和完整性的主要機(jī)制。任何事務(wù)都需要獲得相應(yīng)對象上的鎖才能訪問數(shù)據(jù),讀取數(shù)據(jù)的事務(wù)通常只需要獲得讀鎖(共享鎖),修改數(shù)據(jù)的事務(wù)需要獲得寫鎖(排他鎖)。當(dāng)兩個(gè)事務(wù)互相之間需要等待對方釋放獲得的資源時(shí),如果系統(tǒng)不進(jìn)行干預(yù)則會一直等待下去,也就是進(jìn)入了死鎖(deadlock)狀態(tài)。

以下內(nèi)容適用于各種常見的數(shù)據(jù)庫管理系統(tǒng),包括 Oracle、MySQL、Microsoft SQL Server 以及 PostgreSQL 等。

死鎖是如何產(chǎn)生的?

演示死鎖的產(chǎn)生非常簡單,我們只需要創(chuàng)建一個(gè)包含兩行數(shù)據(jù)的簡單示例表:

CREATE TABLE t_lock(id int PRIMARY KEY, col int);
INSERT INTO t_lock VALUES (1, 100);
INSERT INTO t_lock VALUES (2, 200);

SELECT * FROM t_lock;
id|col|
--+---+
 1|100|
 2|200|

如果我們在不同事務(wù)中以不同的順序修改數(shù)據(jù),就可能引起事務(wù)之間的相互等待。一個(gè)事務(wù)等待另一個(gè)事務(wù)釋放資源不會產(chǎn)生什么問題,但是如果兩個(gè)事務(wù)互相等待對方的資源,數(shù)據(jù)庫管理系統(tǒng)只有兩個(gè)選擇:無限等待或者中止一個(gè)事務(wù)并讓另一個(gè)事務(wù)成功執(zhí)行。

顯然無限等待不是解決問題的方法,因此數(shù)據(jù)庫通常是等待一定時(shí)間之后中止其中一個(gè)事務(wù)。

以下是一個(gè)死鎖的演示案例:

事務(wù)一 事務(wù)二 備注
BEGIN; BEGIN; 分別開始兩個(gè)事務(wù)
UPDATE t_lock
SET col = col + 100
WHERE id = 1;
UPDATE t_lock
SET col = col + 200
WHERE id = 2;
事務(wù)一修改 id=1 的數(shù)據(jù),事務(wù)二修改 id=2 的數(shù)據(jù)
UPDATE t_lock
SET col = col + 100
WHERE id = 2;
事務(wù)一修改 id=2 的數(shù)據(jù),需要等待事務(wù)二釋放寫鎖
等待中… UPDATE t_lock
SET col = col + 200
WHERE id = 1;
事務(wù)二修改 id=1 的數(shù)據(jù),需要等待事務(wù)一釋放寫鎖
死鎖 死鎖 數(shù)據(jù)庫檢測到死鎖,選擇中止一個(gè)事務(wù)
更新成功 返回錯(cuò)誤

對于 MySQL InnoDB,默認(rèn)啟用了 innodb_deadlock_detect 選項(xiàng),事務(wù)二返回以下錯(cuò)誤信息:

ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

如果我們禁用 InnoDB 死鎖檢測選項(xiàng),事務(wù)二在等待 50 s(innodb_lock_wait_timeout )后提示等待超時(shí):

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

Oracle 檢測到死鎖時(shí)返回以下錯(cuò)誤:

ORA-00060: 等待資源時(shí)檢測到死鎖

Microsoft SQL Server 檢測到死鎖時(shí)返回的錯(cuò)誤如下

消息 1205,級別 13,狀態(tài) 51,第 7 行
事務(wù)(進(jìn)程 ID 67)與另一個(gè)進(jìn)程被死鎖在 鎖 資源上,并且已被選作死鎖犧牲品。請重新運(yùn)行該事務(wù)。

PostgreSQL 檢測到死鎖時(shí)返回的錯(cuò)誤如下:

SQL 錯(cuò)誤 [40P01]: 錯(cuò)誤: 檢測到死鎖
  詳細(xì):進(jìn)程32等待在事務(wù) 4765上的ShareLock; 由進(jìn)程16552阻塞.
進(jìn)程16552等待在事務(wù) 4766上的ShareLock; 由進(jìn)程32阻塞.
  建議:詳細(xì)信息請查看服務(wù)器日志.
  在位置:當(dāng)更新關(guān)系"t_lock"的元組(0, 1)時(shí)

如何解決并避免死鎖

死鎖不是數(shù)據(jù)庫自身的問題,我們無法通過優(yōu)化數(shù)據(jù)庫配置來解決或者避免死鎖,只能通過修改應(yīng)用程序來解決。簡單來說,我們應(yīng)該在程序中按照相同的順序修改數(shù)據(jù),避免產(chǎn)生相互等待資源的情況發(fā)生。例如:

事務(wù)一 事務(wù)二 備注
BEGIN; BEGIN; 分別開始兩個(gè)事務(wù)
UPDATE t_lock
SET col = col + 100
WHERE id = 1;

UPDATE t_lock
SET col = col + 200
WHERE id = 1;
事務(wù)一和事務(wù)二都修改 id=1 的數(shù)據(jù),后執(zhí)行的事務(wù)需要等待
UPDATE t_lock
SET col = col + 100
WHERE id = 2;
等待中… 事務(wù)一修改 id=1 的數(shù)據(jù),事務(wù)二等待中
COMMIT; 等待中… 事務(wù)一提交
UPDATE t_lock
SET col = col + 200
WHERE id = 2;
事務(wù)二繼續(xù)修改 id=2 的數(shù)據(jù)
COMMIT; 事務(wù)二提交

以上場景不會產(chǎn)生死鎖。不過,我們在實(shí)際應(yīng)用中可能無法完全按照相同順序修改數(shù)據(jù)。如果出現(xiàn)了不可避免的死鎖情況,另一種解決方法就是捕獲系統(tǒng)返回的死鎖異常并在程序中加入重試機(jī)制。

總結(jié)

本文簡要介紹了數(shù)據(jù)庫死鎖產(chǎn)生的原因和解決方法。到此這篇關(guān)于5分鐘快速了解數(shù)據(jù)庫死鎖產(chǎn)生的場景和解決方法的文章就介紹到這了,更多相關(guān)數(shù)據(jù)庫死鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • mysql 數(shù)據(jù)庫死鎖原因及解決辦法
  • Mysql 數(shù)據(jù)庫死鎖過程分析(select for update)
  • 簡單說明Oracle數(shù)據(jù)庫中對死鎖的查詢及解決方法
  • InnoDB數(shù)據(jù)庫死鎖問題處理
  • Mybatis update數(shù)據(jù)庫死鎖之獲取數(shù)據(jù)庫連接池等待
  • MySQL數(shù)據(jù)庫的一次死鎖實(shí)例分析
  • 講解Oracle數(shù)據(jù)庫中結(jié)束死鎖進(jìn)程的一般方法
  • 記一次公司倉庫數(shù)據(jù)庫服務(wù)器死鎖過程及解決辦法
  • 查詢Sqlserver數(shù)據(jù)庫死鎖的一個(gè)存儲過程分享
  • MySQL數(shù)據(jù)庫之Purge死鎖問題解析

標(biāo)簽:鶴崗 常德 昆明 葫蘆島 沈陽 石嘴山 招商 保定

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《5分鐘快速了解數(shù)據(jù)庫死鎖產(chǎn)生的場景和解決方法》,本文關(guān)鍵詞  5分鐘,快速,了解,數(shù)據(jù)庫,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《5分鐘快速了解數(shù)據(jù)庫死鎖產(chǎn)生的場景和解決方法》相關(guān)的同類信息!
  • 本頁收集關(guān)于5分鐘快速了解數(shù)據(jù)庫死鎖產(chǎn)生的場景和解決方法的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    鄄城县| 龙门县| 宿州市| 丹棱县| 循化| 辽宁省| 阳信县| 和顺县| 苏尼特右旗| 赣州市| 嘉善县| 奎屯市| 公安县| 绍兴市| 津南区| 绵阳市| 石台县| 奎屯市| 花垣县| 大连市| 桐柏县| 中西区| 阜阳市| 桓台县| 惠水县| 贡觉县| 凤山市| 临漳县| 洪泽县| 鄱阳县| 太湖县| 上饶市| 新蔡县| 舟山市| 杭锦旗| 高邑县| 会泽县| 枣阳市| 彰化市| 洞头县| 略阳县|