鍍金池/ 問(wèn)答/Linux  數(shù)據(jù)庫(kù)  HTML/ mysql 存在則更新,不存在則插入的并發(fā)問(wèn)題

mysql 存在則更新,不存在則插入的并發(fā)問(wèn)題

比如有這樣的場(chǎng)景:

  1. 操作一:檢查表 table 中的 id=2 記錄是否存在,存在,則更新這條記錄,否則插入一條記錄
  2. 操作二:檢查表 table 中的 id=2 記錄是否存在,存在,則更新這條記錄,否則插入一條記錄

有多中這樣的操作,分別被封裝進(jìn)不同的服務(wù)里,請(qǐng)問(wèn)有哪些方法可以防止同時(shí)插入兩(多)條呢?
開(kāi)發(fā)環(huán)境:Spring boot + mybatis
自己看了下,可以用
@Transactional(isolation = Isolation.Serializable) 注解;或是將 id 設(shè)置為 unique;或是用復(fù)合 sql 語(yǔ)句(exist 之類的),請(qǐng)問(wèn)哪種更好,或是有沒(méi)有更好的方法。

各位大神,交流的時(shí)候突然又想起一個(gè)場(chǎng)景:

  1. 操作一:檢查表 table 中的 id=2 記錄是否存在,存在,則直接返回id,否則插入一條記錄
  2. 操作二:檢查表 table 中的 id=2 記錄是否存在,存在,則直接返回id,否則插入一條記錄

有多中這樣的操作,分別被封裝進(jìn)不同的服務(wù)里,請(qǐng)問(wèn)有哪些方法可以防止同時(shí)插入兩(多)條呢?有查詢到 insert ignore 但是這個(gè)方法,如果發(fā)現(xiàn)已有數(shù)據(jù),會(huì)返回0,假如操作1和操作2同時(shí)查詢id=2的記錄發(fā)現(xiàn)不存在,然后操作1插入了一條記錄,并返回自增id,操作2若用insert ignore則返回0,感覺(jué)就不對(duì)了,會(huì)造成誤解,請(qǐng)問(wèn)有沒(méi)有什么好的方法呢?

回答
編輯回答
冷溫柔

replace into t1(id, column) values(2, column)
這個(gè)對(duì)于性能來(lái)說(shuō)更好。

2017年10月26日 22:21
編輯回答
鹿惑

可以嘗試REDIS來(lái)進(jìn)行緩存并去重操作 定時(shí)再將數(shù)據(jù)插入數(shù)據(jù)庫(kù)

2017年12月23日 08:37
編輯回答
單眼皮

如果你的使用場(chǎng)景是高并發(fā)的話,單純的讀庫(kù)是會(huì)有性能問(wèn)題的,因?yàn)榭赡軤可娴絤ysql鎖的使用,個(gè)人建議配合redis集合使用,通過(guò)集合的唯一性來(lái)解決這個(gè)問(wèn)題。
在執(zhí)行操作的時(shí)候先嘗試向集合中添加元素,添加成功則說(shuō)明不存在,添加失敗則說(shuō)明已存在。希望對(duì)你有幫助

2017年4月3日 20:03
編輯回答
孤慣

我是直接加了一個(gè)鎖,但這樣會(huì)影響性能。 若對(duì)性能要求不高可以用我這個(gè)方法。
https://kyle.net.cn/2017/11/0...

2018年7月26日 13:35
編輯回答
憶當(dāng)年

我的做法,可不使用@Transactional注解:

INSERT INTO t1 (a, b, c) VALUES (1, 2, 3) ON DUPLICATE KEY UPDATE id=last_insert_id(id), a=1, b=2, c=3;

這樣執(zhí)行完查詢后可以直接使用Statement.getGeneratedKeys獲取到插入的自增ID或更新的記錄ID

2018年7月9日 15:06
編輯回答
別逞強(qiáng)

第二種場(chǎng)景是不是可以考慮設(shè)置 unique key,使用普通 insert,發(fā)生異常后延遲重試的機(jī)制。

2017年1月11日 22:30
編輯回答
你好胸

這個(gè)就是很典型的并發(fā)問(wèn)題啊,隊(duì)列就解決了。

先把記錄全部入隊(duì),然后統(tǒng)一出隊(duì)。

2017年4月14日 14:23
編輯回答
瘋浪

隔離級(jí)別設(shè)置為可串行化很可能會(huì)影響數(shù)據(jù)庫(kù)性能。
id設(shè)為unique

INSERT INTO t1 (a, b, c) VALUES (1, 2, 3) ON DUPLICATE KEY UPDATE a=1, b=2, c=3;

參考:insert on duplicate

2017年11月7日 20:15