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

高并發(fā)狀態(tài)下Replace Into造成的死鎖問(wèn)題解決

 更新時(shí)間:2023年01月18日 09:55:46   作者:PigeonEssence  
本文主要介紹了高并發(fā)狀態(tài)下Replace Into造成的死鎖問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

1.問(wèn)題出現(xiàn):

在測(cè)試階段,大數(shù)據(jù)并發(fā)的情況下,發(fā)現(xiàn)sql語(yǔ)句造成表的死鎖,過(guò)一段時(shí)間,死鎖消失。于是進(jìn)行排查

報(bào)錯(cuò)如下:

對(duì)應(yīng)的sql語(yǔ)句如下:

    @Insert("replace into ${tableName}( windcode,date, \n" +
            "      code, high, open, low, \n" +
            "      `close`, volume, turnover,gtm_modify) "
            + "values (#{obj.windcode},#{obj.date},#{obj.code},#{obj.high},#{obj.open},#{obj.low},#{obj.close},#{obj.volume},#{obj.turnover},#{obj.updateTime})" )
    int insertOne(@Param("obj") KDTO obj, @Param("tableName") String tableName);

在排除了數(shù)據(jù)問(wèn)題和線程重復(fù)調(diào)用以后,我們關(guān)注了一下sql語(yǔ)句本身。 看了網(wǎng)上很多經(jīng)驗(yàn)分享,覺得問(wèn)題可能出現(xiàn)在 Replace Into 語(yǔ)句上。

2.分析解決

首先我們分析一下為什么并發(fā)replace into導(dǎo)致MySQL死鎖

Replace into 一般作用是,當(dāng)存在沖突時(shí),會(huì)把舊記錄替換成新的記錄。也就是說(shuō)這條語(yǔ)句執(zhí)行,分為了兩個(gè)大步:判斷和執(zhí)行

1.判斷:

首先判斷我們需要操作的記錄是否存在(根據(jù)主鍵或者唯一索引判斷

2.操作:

  • 針對(duì)不存在的記錄,語(yǔ)句會(huì)執(zhí)行insert,插入操作。
  • 針對(duì)已經(jīng)存在的記錄,語(yǔ)句可以拆分為delete+insert操作

測(cè)試:

建立表

插入數(shù)據(jù):

我們使用replace into語(yǔ)句去執(zhí)行一個(gè)已經(jīng)存在的數(shù)據(jù):

可以清楚的發(fā)現(xiàn),影響的行數(shù)是兩行

第一行的數(shù)據(jù)被修改了

我們使用replace into語(yǔ)句去執(zhí)行一個(gè)不存在的數(shù)據(jù):

可以清楚的發(fā)現(xiàn),影響的行數(shù)是一行

執(zhí)行了插入操作:

邏輯非常的清晰,但是這種單條sql語(yǔ)句在什么情況下會(huì)出現(xiàn)死鎖呢?我們就要去考慮這個(gè)加鎖的時(shí)機(jī)。

正常的插入邏輯是:

  • 首先插入聚集索引記錄,在上例中id列為自增列。
  • 隨后插入二級(jí)索引num,由于其是唯一索引,在檢查duplicate key時(shí),為其加上類型為L(zhǎng)OCK_X的記錄鎖。

發(fā)現(xiàn)錯(cuò)誤:

  • 由于檢測(cè)到duplicate key,因此第一步插入的聚集索引記錄需要被回滾掉(row_undo_ins)。
  • 從InnoDB層失敗返回到Server層后,收到duplicate key錯(cuò)誤,首先檢索唯一鍵沖突的索引,并對(duì)沖突的索引記錄(及聚集索引記錄)加鎖。

轉(zhuǎn)換模式:

如果發(fā)生uk沖突的索引是最后一個(gè)唯一索引、沒有外鍵引用、且不存在delete trigger時(shí),使用UPDATE ROW的方式來(lái)解決沖突;
否則,使用DELETE ROW + INSERT ROW的方式解決沖突。

更新記錄:

  • 對(duì)于聚集索引,由于PK列發(fā)生變化,采用delete + insert 聚集索引記錄的方式更新。
  • 對(duì)于二級(jí)uk索引,同樣采用標(biāo)記刪除 + 插入的方式。

所以死鎖的問(wèn)題多半就會(huì)出現(xiàn)在X記錄鎖上面。

死鎖分析:

所以再多線程高并發(fā)的環(huán)境狀態(tài)下,存在兩個(gè)事務(wù)同時(shí)去獲取一個(gè)記錄的修改的情況:

  • 事務(wù)1拿到X記錄鎖,
  • 事務(wù)2檢測(cè)到?jīng)_突,獲取X|NK鎖,被事務(wù)1阻塞
  • 事務(wù)1檢測(cè)到?jīng)_突,申請(qǐng)獲取S|NK,被事務(wù)2阻塞
事務(wù)1事務(wù)2
LOCK_X LOCK_NOT_GAP-
-LOCK_X-LOCK_NEXT_KEY 阻塞
LOCK_S-LOCK_NEXT_KEY死鎖回滾

 所以在等待執(zhí)行期間sql會(huì)有死鎖報(bào)錯(cuò),高并發(fā)環(huán)境下的死鎖也就出現(xiàn)了,再事務(wù)執(zhí)行完成回滾操作以后,死鎖回滾,也就解釋了死鎖消失的問(wèn)題。

3.解決方案:

經(jīng)過(guò)多方討論,最終決定使用 insetr + ON DUPLICATE KEY UPDATE語(yǔ)句替換高并發(fā)環(huán)境下的Replace Into語(yǔ)句解決死鎖問(wèn)題。

ON DUPLICATE KEY UPDATE語(yǔ)句的作用是:

若該數(shù)據(jù)的主鍵值/ UNIQUE KEY 已經(jīng)在表中存在,則執(zhí)行更新操作, 即UPDATE 后面的操作。

否則插入一條新的記錄。

實(shí)現(xiàn)了Replace Into有相同的查重替換功能,而避免了高并發(fā)的死鎖問(wèn)題。

但是UPDATE操作性能相比DELETE操作會(huì)有一定的性能上的影響,需要后續(xù)測(cè)試跟進(jìn)。

到此這篇關(guān)于高并發(fā)狀態(tài)下Replace Into造成的死鎖問(wèn)題解決的文章就介紹到這了,更多相關(guān)Replace Into死鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MySQL刪除數(shù)據(jù)庫(kù)的兩種方法

    MySQL刪除數(shù)據(jù)庫(kù)的兩種方法

    這篇文章主要為大家詳細(xì)介紹了MySQL刪除數(shù)據(jù)庫(kù)的兩種方法,感興趣的小伙伴們可以參考一下
    2016-06-06
  • SQL實(shí)現(xiàn)LeetCode(181.員工掙得比經(jīng)理多)

    SQL實(shí)現(xiàn)LeetCode(181.員工掙得比經(jīng)理多)

    這篇文章主要介紹了SQL實(shí)現(xiàn)LeetCode(181.員工掙得比經(jīng)理多),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • 通過(guò)實(shí)例分析MySQL中的四種事務(wù)隔離級(jí)別

    通過(guò)實(shí)例分析MySQL中的四種事務(wù)隔離級(jí)別

    SQL標(biāo)準(zhǔn)定義了4種隔離級(jí)別,包括了一些具體規(guī)則,用來(lái)限定事務(wù)內(nèi)外的哪些改變是可見的,哪些是不可見的。下面這篇文章通過(guò)實(shí)例詳細(xì)的給大家分析了關(guān)于MySQL中的四種事務(wù)隔離級(jí)別的相關(guān)資料,需要的朋友可以參考下。
    2017-08-08
  • Windows10下mysql 8.0.12 解壓版安裝圖文教程

    Windows10下mysql 8.0.12 解壓版安裝圖文教程

    這篇文章主要為大家詳細(xì)介紹了Windows10下mysql 8.0.12 解壓版安裝圖文教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • 解析mysql 5.5字符集問(wèn)題

    解析mysql 5.5字符集問(wèn)題

    本篇文章是對(duì)關(guān)于mysql 5.5字符集的問(wèn)題進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • mysql 5.7.17 winx64免安裝版配置方法圖文教程

    mysql 5.7.17 winx64免安裝版配置方法圖文教程

    這篇文章主要為大家詳細(xì)介紹了mysql 5.7.17 winx64免安裝版配置方法圖文教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • MySQL 5.6.14 win32安裝方法(zip版)

    MySQL 5.6.14 win32安裝方法(zip版)

    這篇文章主要介紹了MySQL 5.6.14 win32安裝方法(zip版)的相關(guān)資料,非常不錯(cuò),需要的朋友可以參考下
    2016-08-08
  • MySQL中查詢當(dāng)天數(shù)據(jù)中離時(shí)間點(diǎn)最近的數(shù)據(jù)(兩種方法)

    MySQL中查詢當(dāng)天數(shù)據(jù)中離時(shí)間點(diǎn)最近的數(shù)據(jù)(兩種方法)

    在 MySQL 中,你可以使用 ORDER BY 和 LIMIT 語(yǔ)句來(lái)查詢當(dāng)天數(shù)據(jù)中離指定時(shí)間最近的數(shù)據(jù),本文給大家介紹MySQL中查詢當(dāng)天數(shù)據(jù)中離時(shí)間點(diǎn)最近的數(shù)據(jù),感興趣的朋友一起看看吧
    2023-12-12
  • mysql列轉(zhuǎn)行以及年月分組實(shí)例

    mysql列轉(zhuǎn)行以及年月分組實(shí)例

    下面小編就為大家?guī)?lái)一篇mysql列轉(zhuǎn)行以及年月分組實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-03-03
  • MySQL安裝常見報(bào)錯(cuò)處理方法總結(jié)大全

    MySQL安裝常見報(bào)錯(cuò)處理方法總結(jié)大全

    MySQL數(shù)據(jù)庫(kù)在安裝或卸載的過(guò)程中,常常會(huì)出現(xiàn)一些錯(cuò)誤,這是件讓我們頭疼的事,下面這篇文章主要給大家介紹了關(guān)于MySQL安裝常見報(bào)錯(cuò)處理方法的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07

最新評(píng)論