最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

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

報錯如下:

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

    @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ù)問題和線程重復(fù)調(diào)用以后,我們關(guān)注了一下sql語句本身。 看了網(wǎng)上很多經(jīng)驗分享,覺得問題可能出現(xiàn)在 Replace Into 語句上。

2.分析解決

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

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

1.判斷:

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

2.操作:

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

測試:

建立表

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

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

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

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

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

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

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

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

正常的插入邏輯是:

  • 首先插入聚集索引記錄,在上例中id列為自增列。
  • 隨后插入二級索引num,由于其是唯一索引,在檢查duplicate key時,為其加上類型為LOCK_X的記錄鎖。

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

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

轉(zhuǎn)換模式:

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

更新記錄:

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

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

死鎖分析:

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

  • 事務(wù)1拿到X記錄鎖,
  • 事務(wù)2檢測到?jīng)_突,獲取X|NK鎖,被事務(wù)1阻塞
  • 事務(wù)1檢測到?jī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會有死鎖報錯,高并發(fā)環(huán)境下的死鎖也就出現(xiàn)了,再事務(wù)執(zhí)行完成回滾操作以后,死鎖回滾,也就解釋了死鎖消失的問題。

3.解決方案:

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

ON DUPLICATE KEY UPDATE語句的作用是:

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

否則插入一條新的記錄。

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

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

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

相關(guān)文章

  • MySQL之臨時表的實現(xiàn)示例

    MySQL之臨時表的實現(xiàn)示例

    MySQL臨時表是存儲在內(nèi)存或者磁盤上的臨時數(shù)據(jù)表,它們的生命周期只限于當(dāng)前數(shù)據(jù)庫會話,臨時表的創(chuàng)建和使用方式與普通表類似,本文就詳細的介紹了MySQL之臨時表,感興趣的可以了解一下
    2023-08-08
  • MySQL時區(qū)查看及設(shè)置全過程

    MySQL時區(qū)查看及設(shè)置全過程

    在服務(wù)器環(huán)境下,MySQL默認時區(qū)可能是UTC,需注意應(yīng)用時區(qū)設(shè)置,若查詢條件使用Now()/sysdate(),會根據(jù)MySQL時區(qū)查詢,導(dǎo)致時間錯亂,可使用`selectnow()`檢查時間準確性,查看和修改MySQL時區(qū)的方法包括使用命令和修改配置文件
    2025-01-01
  • MySQL執(zhí)行.sql?文件的超詳細教學(xué)指南

    MySQL執(zhí)行.sql?文件的超詳細教學(xué)指南

    和其他數(shù)據(jù)庫一樣,MySQL也提供了命令執(zhí)行sql腳本文件,方便地進行數(shù)據(jù)庫、表以及數(shù)據(jù)等各種操作,這篇文章主要給大家介紹了關(guān)于MySQL執(zhí)行.sql?文件的超詳細教學(xué)指南,需要的朋友可以參考下
    2024-07-07
  • mysql show processlist 顯示mysql查詢進程

    mysql show processlist 顯示mysql查詢進程

    processlist命令的輸出結(jié)果顯示了有哪些線程在運行,可以幫助識別出有問題的查詢語句,兩種方式使用這個命令
    2012-03-03
  • MySQL多版本并發(fā)控制MVCC詳解

    MySQL多版本并發(fā)控制MVCC詳解

    這篇文章主要介紹了MySQL多版本并發(fā)控制MVCC詳解,MVCC是通過數(shù)據(jù)行的多個版本管理來實現(xiàn)數(shù)據(jù)庫的并發(fā)控制,這項技術(shù)使得在InnoDB的事務(wù)隔離級別下執(zhí)行一致性讀操作有了保證
    2022-07-07
  • MYSQL日志與備份還原問題詳解

    MYSQL日志與備份還原問題詳解

    這篇文章主要為大家詳細介紹了MYSQL日志與備份還原問題,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • 使用use index優(yōu)化sql查詢的詳細介紹

    使用use index優(yōu)化sql查詢的詳細介紹

    本篇文章是對使用use index優(yōu)化sql查詢進行了詳細的分析介紹,需要的朋友參考下
    2013-06-06
  • MySQL借助DB實現(xiàn)分布式鎖思路詳解

    MySQL借助DB實現(xiàn)分布式鎖思路詳解

    這篇文章主要給大家介紹了關(guān)于MySQL借助DB實現(xiàn)分布式鎖思路的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用MySQL具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • MySQL過濾數(shù)據(jù)操作方法梳理

    MySQL過濾數(shù)據(jù)操作方法梳理

    數(shù)據(jù)庫表一般包含大量的數(shù)據(jù),很少需要檢索表中的所有行。通常只是根據(jù)特定的需要提取表數(shù)據(jù)的子集。因此檢索所需數(shù)據(jù)時需要指定搜索條件,搜索條件也稱為過濾條件
    2022-10-10
  • Mysql主從復(fù)制作用和工作原理詳解

    Mysql主從復(fù)制作用和工作原理詳解

    這篇文章主要介紹了Mysql主從復(fù)制作用和工作原理詳解,主從復(fù)制,是用來建立一個和主數(shù)據(jù)庫完全一樣的數(shù)據(jù)庫環(huán)境,稱為從數(shù)據(jù)庫,主數(shù)據(jù)庫一般是準實時的業(yè)務(wù)數(shù)據(jù)庫,需要的朋友可以參考下
    2019-07-07

最新評論

台南县| 卓尼县| 兴仁县| 林甸县| 阿图什市| 阳朔县| 万宁市| 吴江市| 贵州省| 深水埗区| 潮州市| 南阳市| 勃利县| 汶上县| 黄陵县| 安西县| 驻马店市| 平陆县| 永昌县| 锡林浩特市| 琼中| 景宁| 江口县| 望城县| 涞水县| 吴川市| 宾川县| 红河县| 尉犁县| 建湖县| 大英县| 洞头县| 海林市| 广东省| 云梦县| 赣榆县| 合川市| 南宫市| 闽清县| 长沙市| 甘洛县|