国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 網站 > 幫助中心 > 正文

InnoDB數據庫死鎖問題處理

2024-07-09 22:47:44
字體:
來源:轉載
供稿:網友

場景描述

在update表的時候出現DeadlockLoserDataAccessException異常 (Deadlock found when trying to get lock; try restarting transaction...)。

問題分析

這個異常并不會影響用戶使用,因為數據庫遇到死鎖會自動回滾并重試。用戶的感覺就是操作稍有卡頓。但是監控老是報異常,所以需要解決一下。

解決方法

在應用程序中update的地方使用try-catch。

我自己封裝了一個函數,如下。

/** * 2016-03-15 * linxuan * handle deadlock while update table */ private void updateWithDeadLock(TestMapper mapper, Test record) throws InterruptedException { boolean oops; int retries = 5; do{ oops = false; try{ mapper.updateByPrimaryKeySelective(record); } catch (DeadlockLoserDataAccessException dlEx){ oops = true; Thread.sleep((long) (Math.random() * 500)); } finally { } } while(oops == true && retries-- >0); }

我用的是mybatis,所以只需將mapper傳進函數,如果不用mybatis,需要自己創建并關閉數據庫連接。

延伸:數據庫死鎖

數據庫死鎖是事務性數據庫 (如SQL Server, MySql等)經常遇到的問題。除非數據庫死鎖問題頻繁出現導致用戶無法操作,一般情況下數據庫死鎖問題不嚴重。在應用程序中進行try-catch就可以。那么數據死鎖是如何產生的呢?

InnoDB實現的是行鎖 (row level lock),分為共享鎖 (S) 和 互斥鎖 (X)。

共享鎖用于事務read一行。
互斥鎖用于事務update或delete一行。
當客戶A持有共享鎖S,并請求互斥鎖X;同時客戶B持有互斥鎖X,并請求共享鎖S。以上情況,會發生數據庫死鎖。如果還不夠清楚,請看下面的例子。

數據庫死鎖例子

首先,客戶A創建一個表T,并向T中插入一條數據,客戶A開始一個select事務,所以拿著共享鎖S。

mysql> CREATE TABLE t (i INT) ENGINE = InnoDB;Query OK, 0 rows affected (1.07 sec)mysql> INSERT INTO t (i) VALUES(1);Query OK, 1 row affected (0.09 sec)mysql> START TRANSACTION;Query OK, 0 rows affected (0.00 sec)mysql> SELECT * FROM t WHERE i = 1 LOCK IN SHARE MODE;+------+| i |+------+| 1 |+------+

然后,客戶B開始一個新事務,新事務是delete表T中的唯一一條數據。

mysql> START TRANSACTION;Query OK, 0 rows affected (0.00 sec)mysql> DELETE FROM t WHERE i = 1;

刪除操作需要互斥鎖 (X),但是互斥鎖X和共享鎖S是不能相容的。所以刪除事務被放到鎖請求隊列中,客戶B阻塞。

最后,客戶A也想刪除表T中的那條數據:

mysql> DELETE FROM t WHERE i = 1;ERROR 1213 (40001): Deadlock found when trying to get lock;try restarting transaction
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 米泉市| 鱼台县| 通江县| 墨玉县| 荥阳市| 石家庄市| 永济市| 遵义市| 辽阳县| 张北县| 茶陵县| 读书| 崇文区| 马关县| 广昌县| 马边| 阳江市| 青浦区| 白山市| 镇沅| 通州区| 屯昌县| 密云县| 泸水县| 许昌市| 佛学| 忻城县| 江达县| 洞头县| 绵阳市| 横峰县| 洛扎县| 梓潼县| 上饶县| 西乌珠穆沁旗| 杂多县| 葫芦岛市| 柏乡县| 阳谷县| 普安县| 象山县|