欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

InnoDB數(shù)據(jù)庫死鎖問題處理

 更新時(shí)間:2016年03月16日 11:33:52   投稿:hebedich  
本文給大家講解的是mysql數(shù)據(jù)庫InnoDB類型,在update表的時(shí)候出現(xiàn)死鎖現(xiàn)象的原因及解決辦法,有需要的小伙伴可以參考下。

場(chǎng)景描述

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

問題分析

這個(gè)異常并不會(huì)影響用戶使用,因?yàn)閿?shù)據(jù)庫遇到死鎖會(huì)自動(dòng)回滾并重試。用戶的感覺就是操作稍有卡頓。但是監(jiān)控老是報(bào)異常,所以需要解決一下。

解決方法

在應(yīng)用程序中update的地方使用try-catch。

我自己封裝了一個(gè)函數(shù),如下。

/**
   * 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傳進(jìn)函數(shù),如果不用mybatis,需要自己創(chuàng)建并關(guān)閉數(shù)據(jù)庫連接。

延伸:數(shù)據(jù)庫死鎖

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

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

共享鎖用于事務(wù)read一行。
互斥鎖用于事務(wù)update或delete一行。
當(dāng)客戶A持有共享鎖S,并請(qǐng)求互斥鎖X;同時(shí)客戶B持有互斥鎖X,并請(qǐng)求共享鎖S。以上情況,會(huì)發(fā)生數(shù)據(jù)庫死鎖。如果還不夠清楚,請(qǐng)看下面的例子。

數(shù)據(jù)庫死鎖例子

首先,客戶A創(chuàng)建一個(gè)表T,并向T中插入一條數(shù)據(jù),客戶A開始一個(gè)select事務(wù),所以拿著共享鎖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開始一個(gè)新事務(wù),新事務(wù)是delete表T中的唯一一條數(shù)據(jù)。

mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

mysql> DELETE FROM t WHERE i = 1;

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

最后,客戶A也想刪除表T中的那條數(shù)據(jù):

mysql> DELETE FROM t WHERE i = 1;
ERROR 1213 (40001): Deadlock found when trying to get lock;
try restarting transaction

死鎖產(chǎn)生了!因?yàn)榭蛻鬉需要鎖X來刪除行,而客戶B拿著鎖X并正在等待客戶A釋放鎖S??纯纯蛻鬉,B的狀態(tài):

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

發(fā)生死鎖后,InnoDB會(huì)為對(duì)一個(gè)客戶產(chǎn)生錯(cuò)誤信息并釋放鎖。返回給客戶的信息:

ERROR 1213 (40001): Deadlock found when trying to get lock;
try restarting transaction
所以,另一個(gè)客戶可以正常執(zhí)行任務(wù)。死鎖結(jié)束。

相關(guān)文章

  • 關(guān)于MySQL數(shù)據(jù)庫死鎖的案例和解決方案

    關(guān)于MySQL數(shù)據(jù)庫死鎖的案例和解決方案

    MySQL Update語句防止死鎖是指在修改MySQL數(shù)據(jù)庫的數(shù)據(jù)時(shí),為避免多個(gè)進(jìn)程同時(shí)修改同一數(shù)據(jù)行而造成死鎖的情況,引入了一些機(jī)制來防止死鎖的產(chǎn)生,本文介紹了一個(gè) MySQL 數(shù)據(jù)庫死鎖的案例和解決方案,需要的朋友可以參考下
    2023-09-09
  • MySQL實(shí)現(xiàn)簡(jiǎn)單的創(chuàng)建庫和創(chuàng)建表操作方法

    MySQL實(shí)現(xiàn)簡(jiǎn)單的創(chuàng)建庫和創(chuàng)建表操作方法

    MySQL是最常用的數(shù)據(jù)庫,在數(shù)據(jù)庫操作中基本都是增刪改查操作,簡(jiǎn)稱CRUD,這篇文章主要給大家介紹了關(guān)于MySQL實(shí)現(xiàn)簡(jiǎn)單的創(chuàng)建庫和創(chuàng)建表操作方法的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • MySQL如何修改賬號(hào)的IP限制條件詳解

    MySQL如何修改賬號(hào)的IP限制條件詳解

    這篇文章主要給大家介紹了關(guān)于MySQL如何修改賬號(hào)的IP限制條件的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-08-08
  • mysql數(shù)據(jù)庫優(yōu)化需要遵守的原則

    mysql數(shù)據(jù)庫優(yōu)化需要遵守的原則

    這是我在網(wǎng)上看到的一篇不錯(cuò)的mysql數(shù)據(jù)庫優(yōu)化文章,拿出來和大家分享,希望可以幫助你們
    2012-12-12
  • Mysql添加字段或索引導(dǎo)致鎖表的處理方式

    Mysql添加字段或索引導(dǎo)致鎖表的處理方式

    我們后端開發(fā)人員在實(shí)現(xiàn)業(yè)務(wù)修改時(shí),經(jīng)常需要更新數(shù)據(jù)庫表結(jié)構(gòu),如增加字段、修改字段長(zhǎng)度等等,下面這篇文章主要給大家介紹了關(guān)于Mysql添加字段或索引導(dǎo)致鎖表的處理方式,需要的朋友可以參考下
    2023-05-05
  • linux系統(tǒng)中mysql數(shù)據(jù)庫的導(dǎo)入和導(dǎo)出

    linux系統(tǒng)中mysql數(shù)據(jù)庫的導(dǎo)入和導(dǎo)出

    本文給大家簡(jiǎn)單記錄了一下在linux系統(tǒng)中mysql數(shù)據(jù)庫的導(dǎo)入和導(dǎo)出的方法,有相同需求的小伙伴可以參考下
    2016-02-02
  • 解決mysql報(bào)錯(cuò)ERROR 1049 (42000): Unknown database ‘?dāng)?shù)據(jù)庫‘的問題

    解決mysql報(bào)錯(cuò)ERROR 1049 (42000): Unknown dat

    對(duì)于錯(cuò)誤代碼1049(42000):Unknown database ‘?dāng)?shù)據(jù)庫‘,這個(gè)錯(cuò)誤通常表示您正在嘗試訪問一個(gè)不存在的數(shù)據(jù)庫,本文給出了解決方法,您可以按照文中步驟進(jìn)行操作,需要的朋友可以參考下
    2024-01-01
  • MySQL普通表如何轉(zhuǎn)換成分區(qū)表

    MySQL普通表如何轉(zhuǎn)換成分區(qū)表

    分表和表分區(qū)的目的就是減少數(shù)據(jù)庫的負(fù)擔(dān),提高數(shù)據(jù)庫的效率,通常點(diǎn)來講就是提高表的增刪改查效率,下面這篇文章主要給大家介紹了關(guān)于MySQL普通表如何轉(zhuǎn)換成分區(qū)表的相關(guān)資料,需要的朋友可以參考下
    2022-05-05
  • MySQL中CONCAT和GROUP_CONCAT方法的區(qū)別詳解

    MySQL中CONCAT和GROUP_CONCAT方法的區(qū)別詳解

    本文主要介紹了MySQL中CONCAT和GROUP_CONCAT方法的區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • 淺析MySQL的注入安全問題

    淺析MySQL的注入安全問題

    這篇文章主要介紹了淺析MySQL的注入安全問題,文中簡(jiǎn)單說道了如何避免SQL注入敞開問題的方法,需要的朋友可以參考下
    2015-05-05

最新評(píng)論