今天帶著學生學習了redis的事務功能,redis的事務與傳統的關係型資料庫(如mysql)有所不同,redis的事務不能回滾。
redis中使用multi、exec、discard、watch、unwatch等命令來操作事務。
例如:> multi
ok> incr aaa
queued
> incr bbb
queued
> exec
1) (integer) 1
2) (integer) 1
multi命令表示啟動事務(begin transaction),exec表示執行事務(commit),如果中間的操作有錯誤,有兩種情形:
1.語法錯誤,表現為在exec執行前,命令不能正常新增到queue中。例如,命令出現語法錯誤等。
2. **在執行的時候錯誤,表現為在exec執行後,命令不能正確執行。例如,將string當做list操作。此種操作比較奇怪,在redis事務中,並不會因為中間失敗了導致整個不能執行,而是將正確的部分執行了。有種觀點認為 redis 處理事務的做法會產生 bug ,然而需要注意的是,在通常情況下,回滾並不能解決程式設計錯誤帶來的問題,並且這類錯誤通常不會在生產環境**現,所以 redis 選擇了更簡單、更快速的無回滾方式來處理事務。
那麼這種事務如何去實現秒殺功能呢。答案是使用watch,watch能監控某乙個key的變化,在事務執行時,如果其他的client改變了這個可以所對應的值,將會導致當前client的事務不執行,即類似於樂觀鎖機制。
示例**如下:
首先沒有watch的**:
示例為有10張優惠券,有多人來搶,需要提供秒殺功能。
首先在redis中設定乙個key為num值為0:
命令為:set num 0
public class mythread extends thread catch (interruptedexception e) catch (interruptedexception e) else {
system.out.println(watch + "==="+list+"----" + name + "搶到一張優惠券");
測試結果,你會發現,雖然一樣會有多人去搶,但是始終只有10個人能正取的搶到。
Redis事務和實現秒殺功能的實現
今天帶著學生學習了redis的事務功能,redis的事務與傳統的關係型資料庫 如mysql 有所不同,redis的事務不能回滾。redis中使用multi exec discard watch unwatch等命令來操作事務。例如 multi ok incr aaa queued incr bbb ...
Redis事務和秒殺業務設計
redis事務是乙個單獨的隔離操作 事務中的所有命令都會序列化 按順序地執行。事務在執行的過程中,不會被其他客戶端傳送來的命令請求所打斷,redis事務的主要作用就是串聯多個命令防止別的命令插隊 multi 用於標記事務塊的開始。redis會將後續的命令逐個放入佇列中,然後才能使用exec命令原子化...
redis實現高併發下的搶購 秒殺功能
常規寫法 查詢出對應商品的庫存,看是否大於0,然後執行生成訂單等操作,但是在判斷庫存是否大於0處,如果在高併發下就會有問題,導致庫存量出現負數 redis的解決方案 1,inlcude oncea include db.php redis new redis resid connect 127.0....