1. 程式人生 > >秒殺系統資料同步(保證不多賣)

秒殺系統資料同步(保證不多賣)

正文

東西不多賣

秒殺系統需要保證東西不多賣,關鍵是在多個客戶端對庫存進行減操作時,必須加鎖。Redis中的Watch剛好可以實現一點。首先我們需要獲取當前庫存,只有庫存中的食物小於購物車的數目才能對庫存進行減。在高併發的情況下會出現某時刻查詢庫存夠的,但下一時刻另外一個執行緒下單了,對庫存進行減操作,剛好小於上個執行緒的購物車數目。照理現在的狀態是不能下單成功的,因為庫存已經不夠了,但上一執行緒仍然認為數量還夠,對庫存進行減操作,從而導致庫存出現負數的情況。如何避免?

Redis 中的watch可以在事務前對資料進行監控,如果在事務執行前,該資料發生改變,則事務不執行。剛好能滿足我們的要求。看了很多程式碼,對watch功能還不是很理解,因為網上很多寫的帖子都沒有明確指出多客戶端(理解之後發現還是有寫的),所以不明白的可以參見下面的例子,是用Java寫的。以下程式碼可以保證庫存不多賣。

在redis中設定一個鍵為mykey,值為1000的變數,

public class Main {

    public static void main(String[] args) {
            new MyThread().start();
            new MyThread().start();
            new MyThread().start();
            new MyThread().start();
            new MyThread().start();
            new MyThread().start();
            new
MyThread().start(); new MyThread().start(); new MyThread().start(); new MyThread().start(); } } class MyThread extends Thread { Jedis jedis = null; @Override public void run() { // TODO Auto-generated method stub while (true) { System.out.println(Thread.currentThread().getName()); jedis = RedisUtil.getJedis(); try
{ int stock = Integer.parseInt(jedis.get("mykey")); if (stock > 0) { jedis.watch("mykey"); Transaction transaction = jedis.multi(); transaction.set("mykey", String.valueOf(stock - 1)); List<Object> result = transaction.exec(); if (result == null || result.isEmpty()) { System.out.println("Transaction error...");// 可能是watch-key被外部修改,或者是資料操作被駁回 } } else { System.out.println("庫存為0"); break; } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); RedisUtil.returnResource(jedis); }finally{ RedisUtil.returnResource(jedis); } } } }

Redis保證從資料只加載一次

我這裡碰到的需求是一開始要從Mysql資料庫中匯入資料到Redis,由於有多臺伺服器,不進行控制會對資料進行多次載入,所以我們可以設定一個鍵值進行控制。

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Response;
import redis.clients.jedis.Transaction;
public class Main {

    public static void main(String[] args) {
            new lock().start();
            new lock().start();
            new lock().start();
            new lock().start();
            new lock().start();
            new lock().start();
            new lock().start();
            new lock().start();
            new lock().start();
            new lock().start();
    }
}

class lock extends Thread{

    @Override
    public void run() {
        // TODO Auto-generated method stub
        System.out.println(Thread.currentThread().getName());
        Jedis jedis = null;
        try {
            jedis = RedisUtil.getJedis();
            if(jedis.setnx("look", "1") == 1){
                jedis.set("food", Thread.currentThread().getName());
            }else{
                System.out.println(Thread.currentThread().getName() + "未訪問");
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            RedisUtil.returnResource(jedis);
        }finally{
            RedisUtil.returnResource(jedis);
        }
    }

}

相關推薦

redis系統資料同步保證

秒殺系統需要保證東西不多賣,關鍵是在多個客戶端對庫存進行減操作時,必須加鎖。Redis中的Watch剛好可以實現一點。首先我們需要獲取當前庫存,只有庫存中的食物小於購物車的數目才能對庫存進行減。在高併發的情況下會出現某時刻查詢庫存夠的,但下一時刻另外一個執行緒下單了

系統資料同步保證

正文 東西不多賣 秒殺系統需要保證東西不多賣,關鍵是在多個客戶端對庫存進行減操作時,必須加鎖。Redis中的Watch剛好可以實現一點。首先我們需要獲取當前庫存,只有庫存中的食物小於購物車的數目才能對庫存進行減。在高併發的情況下會出現某時刻查

go資料同步sync與atomic包

Golang推薦通過channel 進行通訊和同步,但在實際開發中sync包用的也較多;另外sync下還有一個atomic包,提供了一些底層的原子操作。 原子操作atomic atomic包(sync/atomic)提供了底層的原子級記憶體操作。 共有五種操作:

分散式系統-REDIS高併發、高效能、庫存資料一致、限語言-設計思路一致

一、秒殺系統準備 1、首先需要能夠抗住基本請求流量的伺服器環境 2、高可用的redis環境(叢集、主從、資料持久化) ps:如果你的每秒請求只有幾百幾千一個REDIS完全夠用不需要額外操心,另外秒殺功能產品往往會加一個小梗,那就是開始秒殺時使用者需要填寫兌換的賬號才能發起秒殺,這裡根據使用者

[大資料專案]-系統企業級實戰應用真實工業界案例

2018最新最全大資料技術、專案視訊。整套視訊,非那種淘寶雜七雜八網上能免費找到拼湊的亂八七糟的幾年前的不成體系浪費咱們寶貴時間的垃圾,詳細內容如下,需要的聯絡QQ:3164282908(加Q註明部落格園)。 更有海量大資料技術視訊、大資料專案視訊,機器學習深度學習技術視訊、專案視訊。Python程式設計視

【高併發】系統架構解密,是所有的都是升級版!!

## 寫在前面 > 很多小夥伴反饋說,高併發專題學了那麼久,但是,在真正做專案時,仍然不知道如何下手處理高併發業務場景!甚至很多小夥伴仍然停留在只是簡單的提供介面(CRUD)階段,不知道學習的併發知識如何運用到實際專案中,就更別提如何構建高併發系統了! 究竟什麼樣的系統算是高併發系統?今天,我們就一

redis樂觀鎖適用於系統

修改 導致 代碼 -a 通知 解決 redis服務器 font 變化 redis事務中的WATCH命令和基於CAS的樂觀鎖 在Redis的事務中,WATCH命令可用於提供CAS(check-and-set)功能。假設我們通過WATCH命令在事務執行之前監控了多個Keys,

高並發系統方案

但是 clas image 數據庫 cdn blog 方案 對象 以及 memcatch相比redis而言,無法做持久化。 JSR303:服務端的驗證框架。 首先我們可以將靜態頁面緩存在用戶的瀏覽器端或者是手機端,然後用戶的請求會到達CDN(網站的緩存和鏡

高並發系統方案

nco home null public web IT pro mage 項目 項目框架搭建: DemoController: package com.imooc.miaosha.controller; import org.springframewor

Python Django 集成Redis Sentinel哨兵集群開發系統

django nginx redis集群 sentinel集群 gunicorn django 我們知道秒殺系統最大特點是瞬時高並發、高訪問量的系統。我們還要保證它的高可用性。這裏我們采用Python Django 集成Redis Sentinel(哨兵)集群開發秒殺系統。 Redis S

關於高並發和系統,你知道的和知道的一些事

好的 來看 機器人 線性 就會 用戶訪問 運行時 dos 也會 這篇文章也算是對於課程 《PHP秒殺系統 高並發高性能的極致挑戰》 的一個整理,視頻之外的另外一種形式吧。 大家也許開發過高並發的系統或者秒殺程序,但肯定都有接觸過,像電商平臺的秒殺、搶購等活動,還有1230

SpringBoot實現Java高併發系統之Web層開發

接著上一篇文章:SpringBoot實現Java高併發之Service層開發,今天我們開始講SpringBoot實現Java高併發秒殺系統之Web層開發。 Web層即Controller層,當然我們所說的都是在基於Spring框架的系統上而言的,傳統的SSH專案

SpringBoot實現Java高併發系統之Service層開發

繼上一篇文章:SpringBoot實現Java高併發秒殺系統之DAO層開發 我們建立了SpringBoot專案並熟悉了秒殺系統的表設計,下面我們將講解一下秒殺系統的核心部分:Service業務層的開發。 Service層又稱為業務層,在Spring階段主要是由@

SpringBoot實現Java高併發系統之DAO層開發

秒殺系統在如今電商專案中是很常見的,最近在學習電商專案時講到了秒殺系統的實現,於是打算使用SpringBoot框架學習一下秒殺系統(本專案基於慕課網的一套免費視訊教程:Java高併發秒殺API,視訊教程中講解的很詳細,非常感謝這位講師)。也是因為最近學習了Spr

記慕課學習系統之DAO層

作為一名初學框架的菜鳥,記錄這一次在慕課學習整個框架基礎功能的過程,與大家共勉! 本專案利用SSM框架,完成了秒殺專案簡單的增刪改查功能,對初學框架的小菜鳥(比如我)有非常好的指導作用。 專案開發所用工具:IDEA開發環境,jdk1.8,Mysql 8.0.

系統從SqlServer轉向Mysql儲存,同時進行同步方案系統資料同步

業務系統底層儲存由原先SQLServer轉向Mysql,但由於歷史原因,SQLServer的資料庫與資料需要保留(原先業務的下游系統有很長資料庫同步鏈條),並需要實時與Mysql進行同步(單向同步)以下

業務系統資料庫從SqlServer轉向Mysql系統資料同步

業務系統底層儲存由原先SQLServer轉向Mysql,但由於歷史原因,SQLServer的資料庫與資料需要保留(原先業務的下游系統有很長資料庫同步鏈條),並需要實時與Mysql進行同步(單向同步)以下

nodejs之簡單的系統實現mysql、redis、kafka、zookeeper、postman或docker

nodejs之簡單的秒殺系統實現(mysql、redis、kafka、zookeeper或docker) 一:環境 二:工具說明 三:程式碼實現 四:啟動專案 五:測試 一:環境 1.一臺阿里雲

SSM專案實戰--- 高併發系統之DAO層

專案為慕課網上 搞定Java SSM框架開發的綜合案例–實現一個秒殺系統案例。 1.首先搭建專案 使用Maven構建來管理依賴項,pom.xml檔案: 此pom.xml可作為大多數ssm專案依賴的參考 <project xmlns="http:

系統感悟&待續

秒殺 秒殺系統最重要的就是防止超賣(哈哈)。只要不虧本就行。同時秒殺系統流量一般比較大,採用同步方式效率肯定比較低。 秒殺就是請求過來,減去相應庫存,生成訂單的過程。如果庫存不足,則不能生成訂單。出錯一般就在查詢庫存和減庫存的過程中,不是同步的