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

InnoDB數(shù)據(jù)庫(kù)死鎖問(wèn)題處理

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

場(chǎng)景描述

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

問(wèn)題分析

這個(gè)異常并不會(huì)影響用戶使用,因?yàn)閿?shù)據(jù)庫(kù)遇到死鎖會(huì)自動(dòng)回滾并重試。用戶的感覺(jué)就是操作稍有卡頓。但是監(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ù)庫(kù)連接。

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

數(shù)據(jù)庫(kù)死鎖是事務(wù)性數(shù)據(jù)庫(kù) (如SQL Server, MySql等)經(jīng)常遇到的問(wèn)題。除非數(shù)據(jù)庫(kù)死鎖問(wèn)題頻繁出現(xiàn)導(dǎo)致用戶無(wú)法操作,一般情況下數(shù)據(jù)庫(kù)死鎖問(wèn)題不嚴(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ù)庫(kù)死鎖。如果還不夠清楚,請(qǐng)看下面的例子。

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

首先,客戶A創(chuàng)建一個(gè)表T,并向T中插入一條數(shù)據(jù),客戶A開(kāi)始一個(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開(kāi)始一個(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來(lái)刪除行,而客戶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ù)庫(kù)死鎖的案例和解決方案

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    分表和表分區(qū)的目的就是減少數(shù)據(jù)庫(kù)的負(fù)擔(dān),提高數(shù)據(jù)庫(kù)的效率,通常點(diǎn)來(lái)講就是提高表的增刪改查效率,下面這篇文章主要給大家介紹了關(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ū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • 淺析MySQL的注入安全問(wèn)題

    淺析MySQL的注入安全問(wèn)題

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

最新評(píng)論