記資料庫更新操作中set和and聯合使用的坑

2021-10-10 18:32:20 字數 2450 閱讀 6122

秒殺時候,發現**出現超賣的問題

最原始控制器**:

("/miaosha"

)@controller

public

class

miaoshacontroller

*/long userid =

17367117439l;

//todo change

userid = user.

getid()

; goodvo goods = igoodservice.

getdetailbyid

(goodsid)

;//判斷庫存

int stock = goods.

getstockcount()

;if(stock <=0)

//判斷是否已經秒殺到了

boolean flag = iorderservice.

hasmiaoshaorder

(userid, goodsid);if

(flag)

//減庫存 下訂單 寫入秒殺訂單

order order = imiaoshaservice.

domiaosha

(userid, goods)

; model.

addattribute

("orderinfo"

, order)

; model.

addattribute

("goods"

, goods)

;return

"order_detail";}

}秒殺業務**:

@service

("imiaoshaservice"

)public

class

miaoshaserviceimpl

implements

imiaoshaservice

}

減庫存的mybatis**如下:

"reducecount"

>

update miaosha_goods set stock_count = stock_count -

1goods_id = #

<

/where>

<

/update>

上述**就是先判斷是否還有庫存,如果有庫存再判斷使用者是否已經秒殺成功了,最後才是寫入秒殺訂單。

很明顯,上述**存在問題,高併發下面會有大量使用者同時湧入,此時商品庫存都為正的,但是後面更新庫存的時候,直接將商品數量減成了負數,此時就存在超賣問題。

首先利用資料庫的行鎖,修改sql語句如下:

"reducecount"

>

update miaosha_goods set stock_count = stock_count -

1 and stock_count >

0goods_id = #

<

/where>

<

/update>

沒錯,最開始的**是這樣的!後來直接執行一次sql語句,看了下執行結果。發現庫存直接變為了1!!!不管原來的庫存為多少,只要大於0,都會變為1。

經過分析,其實set語句後面要想更新多個屬性的話,是直接使用」逗號「進行分隔的,要是使用了and,則會根據右側的結果進行與運算。。。

真正可用的sql語句如下:

"reducecount"

>

update miaosha_goods set stock_count = stock_count -

1goods_id = # and stock_count >

0<

/where>

<

/update>

僅僅這麼改是遠遠不夠的,此時如果庫存未更新即當前庫存已為零的時候,還會生成新的訂單,也是超賣問題。

利用事務回滾的特性,解決超賣問題。

修改秒殺業務的**為:

@service

("imiaoshaservice"

)public

class

miaoshaserviceimpl

implements

imiaoshaservice

//下訂單

return iorderservice.

createorder

(userid, goodvo);}

}

ok,現在已經沒有超賣問題了。

資料庫筆記(資料庫操作)

1.windows系統下 資料庫啟動 net start mysql2.連線與斷開伺服器 mysql h 位址 p 埠 u 使用者名稱 p 密碼3.檢視當前資料庫 select database 4.顯示當前時間,使用者名稱,資料庫版本 select now user version 5.建立庫 1...

SqlServer資料庫的常用操作 更新中

以下所有操作均可以在物件資源管理器中執行 1.創ii建資料庫 create database 學生選課資料庫 on name 學生選課 m filename c program files microsoft sql server mssql10 50.mssqlserver mssql data ...

redis快取資料庫 set集合操作

redis的集合允許使用者將任意多個各個不相同的元素儲存到集合裡面,這些元素既可以是文字資料,也可以是二進位制資料。與列表相比,集合有以下兩個明顯的區別。name對應的集合中新增元素sadd name,values 獲取name對應的集合中元素個數 scard name 在第乙個name對應的集合中...