秒殺超賣問題

2021-10-22 21:42:31 字數 3848 閱讀 1155

秒殺問題其實就是併發讀寫的問題,需要解決超賣,效率等問題。可以使用redis將秒殺的資料進行快取,通過啟用定時任務,當redis中的庫存為0時將,快取持久化到資料庫中,並且將redis中的快取清除掉。

@service

@slf4j

public

class

orderserviceimpl

extends

serviceimpl

implements

orderservice

stock stock1 =

(stock)redisutil.

hget

("stock"

, string.

valueof

(sid));

//校驗庫存

if(stock1.

getcount()

<=0)

//校驗使用者是否已經秒殺過

if(redisutil.

hhaskey

("stockorderlist"

,string.

valueof

(userid)))

//減庫存

int oldversion = stock1.

getversion()

; stock1.

setcount

(stock1.

getcount()

-1);

stock1.

setsale

(stock1.

getsale()

+1);

stock1.

setversion

(oldversion +1)

;//更新redis中的庫存資訊

redisutil.

hset

("stock"

,string.

valueof

(sid)

,stock1)

;//建立訂單

stockorder stockorder =

newstockorder()

; stockorder.

setuserid

(userid)

; stockorder.

setsid

(stock1.

getid()

);stockorder.

setname

(stock1.

getname()

);stockorder.

setcreatetime

(new

date()

);hashmap

ordermap = maps.

newhashmap()

; ordermap.

put(string.

valueof

(stock1.

getid()

),stockorder)

; redisutil.

hset

("stockorderlist"

,string.

valueof

(userid)

,stockorder)

; log.

info

("下單成功");

return apiresult.

success

("下單成功");

}}}

啟用定時任務,當庫存為0時,將秒殺的快取資料持久化到資料庫中。

/**

* 秒殺快取的資料持久化到資料庫中

*/@scheduled

(cron =

"0 0/5 * * * ?"

)public

void

seckilltodb()

);}}

);}}

引入依賴:

<

!-- 訊息佇列 --

>

org.springframework.boot<

/groupid>

spring-boot-starter-amqp<

/artifactid>

org.springframework.boot<

/groupid>

spring-boot-starter-logging<

/artifactid>

<

/exclusion>

<

/exclusions>

<

/dependency>

在springboot的啟動類宣告佇列和交換機

/**

* 宣告佇列

* @return 名為 instantbuy 的訊息佇列

*/@bean

public queue instantbuy()

/** * 宣告交換機

* @return 名為 instantbuyexchange 的交換機

*/@bean

public directexchange instantbuyexchange()

/** * 繫結交換機和佇列

* @return 繫結結果

*/@bean

public binding bind()

定義消費者,監聽訊息佇列:

@component

public

class

instantbuyconsumer

return msg +

"_success";}

}

生產者生產訊息:

@override

public apiresult instantbut

(integer sid, integer userid)

long stockinventory = redisutil.

hnum

("stock"

, string.

valueof

(sid),-

1);if

(stockinventory<0)

//判斷該使用者是否秒殺過該商品,如果秒殺過返回已不能重複秒殺

if(redisutil.

hhaskey

("instantsuccess"

,sid +

","+ userid)

)//該使用者可以正常秒殺

string skillresult =

(string)rabbittemplate.

convertsendandreceive

("instantbuyexchange"

,"instantbuy"

, sid +

","+ userid);if

(stringutils.

isnotblank

(skillresult)

&& skillresult.

equals

(sid +

","+ userid +

"_success"))

else

}}

定時任務:

@scheduled

(cron =

"0 0/1 * * * ?"

)public

void

insertgroups()

}

秒殺專案解決賣超問題

如何保證不賣超 有兩種情況可能會導致賣超 1 乙個使用者同時發出了多個請求,如果庫存足夠,沒加限制,使用者就可以下多個訂單。2 減庫存的sql上沒有加庫存數量的判斷,併發的時候也會導致把庫存減成負數。我們的解決辦法 對於 1 前端加驗證碼,防止使用者同時發出多個請求,在後端的miaosha orde...

關於秒殺和超賣的效能問題

一 秒殺帶來了什麼?秒殺或搶購活動一般會經過 預約 搶訂單 支付 這3個大環節,而其中 搶訂單 這個環節是最考驗業務提供方的抗壓能力的。搶訂單環節一般會帶來2個問題 1 高併發 2 超賣 任何商品都會有數量上限,如何避免成功下訂單買到商品的人數不超過商品數量的上限,這是每個搶購活動都要面臨的難題。二...

秒殺系統防止庫存超賣

第一種 通過資料庫樂觀鎖實現 小型電商 update productstocks set realstock realstock where sku and realstock 0 根據受影響的行數判斷是否執行成功 大型網際網路不是這麼玩的 資料庫有瓶頸 第二種 使用redis 分布式鎖實現 var...