Mysql 并發(fā)插入、存在不插入,存在更新操作
我們遇到挺多這樣的問(wèn)題,當(dāng)用戶并發(fā)提交數(shù)據(jù),重復(fù)提交數(shù)據(jù)。導(dǎo)致數(shù)據(jù)重復(fù),或者 Mysql SQL 報(bào)錯(cuò)。
幾種解決辦法,對(duì)應(yīng)到幾種業(yè)務(wù)場(chǎng)景。
方案一,先查再插
這個(gè)應(yīng)該是最常見(jiàn)的處理方式,是醉不安全的,因?yàn)橐坏┯胁l(fā)其實(shí)完全防止不了,來(lái)看看偽代碼。
Entity entity = service.findById(10);
if(null == entity){
service.insert(obj);
}else{
service.update(obj);
}先根據(jù)條件查詢,存在就更新,不存在添加,但是往往我們是集群、多列的狀態(tài)下,會(huì)再你正在判斷null == entity的時(shí)候,另外一個(gè)線程已經(jīng)插入完畢了,導(dǎo)致你以為是不存在,重復(fù)插入。
方案二,存在即更新,不存在即插入
我們平常的INSERT INTO SQL 是這么寫(xiě):
INSERT INTO demo_in(a,b,c) VALUES(123, 2, 4);比如C是主鍵,插入2次就會(huì)拋出異常:
[23000][1062] Duplicate entry '4' for key 'PRIMARY'所以我們用到REPLACE關(guān)鍵字,他的作用如題,存在即更新,不存在即插入,和delete + Insert Into 一樣。但是它一個(gè)原子操作,是一步完成,所以我們不用擔(dān)心有其他問(wèn)題的出現(xiàn),但是使用REPLACE的時(shí)候,一定要保證表有唯一主鍵。
重要:執(zhí)行REPLACE 語(yǔ)句后,系統(tǒng)返回了所影響的行數(shù),如果返回1,說(shuō)明在表中并沒(méi)有重復(fù)的記錄,如果返回2,說(shuō)明有一條重復(fù)記錄,系統(tǒng)自動(dòng)先調(diào)用了DELETE刪除這條記錄,然后再記錄用INSERT來(lái)插入這條記錄。
改造一下上面的語(yǔ)句就是:
REPLACE INTO demo_in(a,b,c) VALUES(123, 2, 4);方案三,存在不插入,不存在再插入
這個(gè)其實(shí)很簡(jiǎn)單,因?yàn)?nbsp; Mysql 不能做到插入的時(shí)候帶where條件,故用了一張臨時(shí)表來(lái)處理。
INSERT INTO demo_in(a,b,c) SELECT 123, 2, 4 FROM DUAL WHERE NOT EXISTS(SELECT c FROM demo_in WHERE c = 4);用臨時(shí)表DUAL來(lái)標(biāo)記數(shù)據(jù),然后插入到demo_in表中。條件是c=4,并且not exists,也就是當(dāng)c=4條件滿足,則不插入。
版權(quán)所屬:SO JSON在線解析
原文地址:http://suancuo.cn/blog/288.html
轉(zhuǎn)載時(shí)必須以鏈接形式注明原始出處及本聲明。
如果本文對(duì)你有幫助,那么請(qǐng)你贊助我,讓我更有激情的寫(xiě)下去,幫助更多的人。
