程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> InnoDB數據庫逝世鎖成績處置

InnoDB數據庫逝世鎖成績處置

編輯:MySQL綜合教程

InnoDB數據庫逝世鎖成績處置。本站提示廣大學習愛好者:(InnoDB數據庫逝世鎖成績處置)文章只能為提供參考,不一定能成為您想要的結果。以下是InnoDB數據庫逝世鎖成績處置正文


場景描寫

在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

逝世鎖發生了!由於客戶A須要鎖X來刪除行,而客戶B拿著鎖X並正在期待客戶A釋放鎖S。看看客戶A,B的狀況:

客戶A: 拿著鎖S,期待著客戶B釋放鎖X。
客戶B: 拿著鎖X,期待著客戶A釋放鎖S。

產生逝世鎖後,InnoDB會為對一個客戶發生毛病信息並釋放鎖。前往給客戶的信息:

ERROR 1213 (40001): Deadlock found when trying to get lock;
try restarting transaction
所以,另外一個客戶可以正常履行義務。逝世鎖停止。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved