鍍金池/ 問答/Java  Linux/ java的一個多并發(fā)問題

java的一個多并發(fā)問題

一個人重復(fù)快速多次添加一條數(shù)據(jù)或者很多人搶某樣?xùn)|西
如果僅僅只是插入前先查詢的話,那么會出現(xiàn)如下所示的情況:

if(用戶不存在)
{
    xxxxx
    存儲用戶到數(shù)據(jù)庫
}
else
{
    重復(fù)推送,不采取任何措施
}

這個操作還沒有執(zhí)行完畢,第二條擁有相同數(shù)據(jù)的線程已經(jīng)進(jìn)入并通過了if的檢驗(yàn),還是導(dǎo)致數(shù)據(jù)庫存儲了兩條相同的數(shù)據(jù)。

synchronized對方法添加同步鎖的話也會影響其他的數(shù)據(jù)啊。而且不想對數(shù)據(jù)庫做唯一索引的操作。

哦對了,我還用到了負(fù)載均衡。

請大家給予一個好的思路,謝謝~

回答
編輯回答
朕略傻

為什么不用唯一索引,就是和自己過不去?

好,就和自己過不去,OK:

最簡單的方法,隊(duì)列

以“很多人搶某樣?xùn)|西”為例,設(shè)一個記錄“搶”的信息表,不刪、不改、只增加、只讀

無論多少人多少條請求,都先添加進(jìn)這個表,不會有什么唯一性問題,也不會沖突

定時任務(wù),讀取這個“搶”的信息表,想怎么處理?取第一個?取前100個?

再更新到實(shí)際的真實(shí)數(shù)據(jù)庫

說到底,就是犧牲時效,保證正確(很多類似這樣的設(shè)計(jì))

總結(jié):“無延時”、“高性能”、“高可用” 不可兼得,這是常識。。。

2018年3月28日 02:55
編輯回答
魚梓

你先設(shè)置好友多少個對象要搶 然后先減1 這個減要是原子的 然后在慢慢的入庫 消息隊(duì)列什么的都可以

2018年3月6日 21:02
編輯回答
不討囍

幾種解決方式。

高并發(fā)下。

  1. 引用mq,使其順序執(zhí)行。但是無法全局順序;
  2. 把Java的if寫到存儲過程中。這樣,java與DB的交互就是一次。java調(diào)用存儲過程,只需要得到執(zhí)行行數(shù)即可。

非高并發(fā)下。

  1. 針對“一個人快速點(diǎn)擊”,請求完,使按鈕置灰色;
  2. 針對“多個人搶購”,增加隊(duì)列(要么mq,要么維護(hù)java內(nèi)存隊(duì)列)順序處理。有單點(diǎn)風(fēng)險(xiǎn)(可做客戶端路由,但是需要增加zk監(jiān)聽,自動發(fā)現(xiàn)機(jī)制。略復(fù)雜)。
2017年11月3日 18:57