国产精品天干天干,亚洲毛片在线,日韩gay小鲜肉啪啪18禁,女同Gay自慰喷水

歡迎光臨散文網(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)遵守國家法律
普陀区| 女性| 馆陶县| 庐江县| 新密市| 纳雍县| 卢氏县| 林西县| 象山县| 温泉县| 潜山县| 全州县| 萨迦县| 新民市| 明水县| 卫辉市| 巴彦县| 泰来县| 藁城市| 崇仁县| 博客| 上饶县| 中牟县| 商洛市| 太和县| 青岛市| 城固县| 集贤县| 虞城县| 綦江县| 句容市| 濮阳市| 大石桥市| 洞口县| 报价| 常熟市| 永福县| 太康县| 安图县| 东乡县| 滨海县|