最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

MySQL的INSERT ... FOR UPDATE你用過嗎

2023-07-24 12:00 作者:會(huì)燒菜的沙師弟  | 我要投稿

引言

了不起最近處理了一個(gè)生產(chǎn)問題,具體情況是這樣的:

就是兩個(gè)sql語句在同一個(gè)代碼塊中,第一個(gè)sql語句是對(duì)設(shè)備狀態(tài)根據(jù)設(shè)備ID批量刪除,第二個(gè)sql語句是批量插入,插入的設(shè)備ID和刪除的設(shè)備ID是同一個(gè)。

本地和測(cè)試環(huán)境當(dāng)時(shí)都好好的,可是上了生產(chǎn)環(huán)境,報(bào)錯(cuò)了

錯(cuò)誤是存在重復(fù)的唯一索引,代碼邏輯很簡(jiǎn)單

可以看到就是一個(gè)批量刪除,再批量插入,測(cè)試環(huán)境當(dāng)時(shí)沒有用多個(gè)實(shí)例進(jìn)行測(cè)試,上產(chǎn)是有多個(gè)實(shí)例的,錯(cuò)誤的發(fā)生情況當(dāng)天下班后一直分析到晚上12點(diǎn),終于分析出來了,如下圖:

可以看到是同時(shí)來了兩個(gè)請(qǐng)求,分別落到了2臺(tái)機(jī)器,這段代碼在2個(gè)機(jī)器上執(zhí)行就不能保證順序性了,這個(gè)要加鎖的話也是分布式鎖。

不過還可以通過數(shù)據(jù)庫的行鎖來實(shí)現(xiàn),接下來我們就一起來看看INSERT ... FOR UPDATE語句。

MySQL的?INSERT ... FOR UPDATE語句可以用于在插入新行的同時(shí)對(duì)這些行進(jìn)行加鎖,從而防止其他事務(wù)對(duì)這些行進(jìn)行修改。下面簡(jiǎn)要介紹?INSERT ... FOR UPDATE語句的原理和應(yīng)用場(chǎng)景,并舉例說明其具體用法。

一、INSERT ... FOR UPDATE語句的原理

INSERT ... FOR UPDATE語句會(huì)在執(zhí)行插入操作時(shí),對(duì)插入的新行進(jìn)行排他鎖(Exclusive Lock)的加鎖操作,從而避免其他事務(wù)對(duì)這些新行進(jìn)行修改。

這種鎖定機(jī)制同樣是基于MySQL的事務(wù)隔離級(jí)別實(shí)現(xiàn)的,只有在可重復(fù)讀(REPEATABLE READ)和串行化(SERIALIZABLE)隔離級(jí)別下,INSERT ... FOR UPDATE語句才能生效。

二、INSERT ... FOR UPDATE語句的應(yīng)用場(chǎng)景

  1. 防止重復(fù)插入

在某些業(yè)務(wù)場(chǎng)景下,可能需要對(duì)某些數(shù)據(jù)進(jìn)行唯一性約束,避免重復(fù)插入相同的數(shù)據(jù)。使用?INSERT ... FOR UPDATE語句可以避免并發(fā)的情況下,多個(gè)事務(wù)同時(shí)插入相同的數(shù)據(jù)。

  1. 實(shí)現(xiàn)悲觀鎖

在某些業(yè)務(wù)場(chǎng)景下,需要對(duì)某些數(shù)據(jù)進(jìn)行嚴(yán)格的控制,確保數(shù)據(jù)不會(huì)被其他事務(wù)修改。使用?INSERT ... FOR UPDATE語句可以實(shí)現(xiàn)悲觀鎖,確保數(shù)據(jù)的安全性。

  1. 實(shí)現(xiàn)樂觀鎖

使用?INSERT ... FOR UPDATE語句可以實(shí)現(xiàn)樂觀鎖機(jī)制,即在插入數(shù)據(jù)的同時(shí),記錄數(shù)據(jù)的版本號(hào)或時(shí)間戳等信息,如果在插入時(shí)發(fā)現(xiàn)版本號(hào)或時(shí)間戳已經(jīng)存在,則說明其他事務(wù)已經(jīng)插入了相同的數(shù)據(jù),需要進(jìn)行相應(yīng)的處理。

三、INSERT ... FOR UPDATE語句的應(yīng)用舉例

下面舉例說明?INSERT ... FOR UPDATE語句的具體用法。

假設(shè)有一個(gè)用戶表user,其中包含用戶ID和用戶名兩個(gè)字段,現(xiàn)在需要往用戶表中插入新用戶,假設(shè)插入流程如下:

  1. 根據(jù)用戶ID查詢用戶是否已經(jīng)存在

  2. 如果用戶不存在,則插入新用戶

在這個(gè)過程中,需要對(duì)用戶ID進(jìn)行唯一性約束,避免重復(fù)插入相同的用戶。

可以使用如下的SQL語句來實(shí)現(xiàn)插入操作:

START TRANSACTION;SELECT * FROM user WHERE user_id = '123' FOR UPDATE;INSERT INTO user(user_id, username) VALUES ('123', 'John');COMMIT;

在這個(gè)SQL語句中,SELECT ... FOR UPDATE語句用于對(duì)選定的行進(jìn)行加鎖,防止其他事務(wù)對(duì)這些行進(jìn)行修改,從而避免重復(fù)插入相同的用戶。如果查詢結(jié)果為空,則可以插入。

四、生產(chǎn)問題的解決

了不起這邊處理的方式就很簡(jiǎn)單了,直接將批量插入sql的語句末尾加上了 FOR UPDATE。
語法參考:

insert into tablename values() on duplicate key update columnName = valueName;

由于具體涉及公司隱私就不貼sql語句了,原理就是當(dāng)執(zhí)行插入的時(shí)候,如果已經(jīng)有這條數(shù)據(jù)存在,那么就更新它,就不會(huì)存在說已經(jīng)插入了的數(shù)據(jù)在插入一條會(huì)報(bào)重復(fù)Key這個(gè)情況。

簡(jiǎn)單的INSERT ... FOR UPDATE你掌握了吧,后面我們繼續(xù)學(xué)習(xí)。


MySQL的INSERT ... FOR UPDATE你用過嗎的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
广丰县| 洛浦县| 云和县| 梅河口市| 丘北县| 宁海县| 宜君县| 通江县| 保山市| 韶山市| 湖北省| 永顺县| 九龙城区| 普宁市| 大石桥市| 安义县| 扬州市| 云梦县| 天祝| 离岛区| 榆中县| 汾阳市| 固阳县| 雷州市| 德清县| 新民市| 武隆县| 霍林郭勒市| 丹棱县| 越西县| 衡水市| 阳西县| 米易县| 共和县| 秀山| 祁门县| 抚远县| 多伦县| 翁牛特旗| 达尔| 石棉县|