Inhaltsverzeichnis
1 Um die Coupon-Flash-Sale-Funktion zu implementieren
Also, warum tritt dieses Problem auf?
Heim Datenbank Redis So lösen Sie das Redis-Coupon-Flash-Sale-Problem

So lösen Sie das Redis-Coupon-Flash-Sale-Problem

May 28, 2023 pm 02:52 PM
redis

1 Um die Coupon-Flash-Sale-Funktion zu implementieren

So lösen Sie das Redis-Coupon-Flash-Sale-Problem

müssen Sie bei der Bestellung zwei Punkte beurteilen: 1. Ob der Flash-Sale beginnt oder endet 2. Ob der Lagerbestand ausreicht

Unsere Geschäftslogik lautet also wie folgt folgt

1. Erhalten Sie Coupon-Informationen über die Coupon-ID

2. Stellen Sie fest, ob der Flash-Sale begonnen hat, wenn keine Fehlermeldung zurückgegeben wird. 3. Stellen Sie fest, ob der Flash-Sale beendet ist, und geben Sie eine Fehlermeldung zurück, wenn er beendet ist

4. Wenn es innerhalb der Flash-Sale-Zeit ist, ermitteln Sie, ob der Lagerbestand ausreichend ist.

6.1 Bestell-ID speichern 6.2 Benutzer-ID speichern Der obige Code unter hoher Parallelität. (Mit dem JMX-Tool)

Das Bild unten zeigt, dass zweihundert Threads erstellt und sofort eine Gutscheinanfrage gestellt wurden

Aber wenn wir uns den Aggregationsbericht ansehen, stellen wir fest, dass der Ausreißerwert nur 45,5 % beträgt , was logischerweise 50 % sein sollte. (Da 100 Einheiten auf Lager sind, wurden hier 200 Anfragen gesendet)

Wenn man sich die Inventarnummer ansieht, gute Leute, ist sie -9

So lösen Sie das Redis-Coupon-Flash-Sale-Problem

Die Bestellung hat auch wurden auf 109 Einheiten erhöht, was offensichtlich zu einem Überverkaufsproblem führte.

Also, warum tritt dieses Problem auf?

Schauen Sie sich die Bilder an und sprechen Sie:

Folgen Sie unserem normalen Prozess, das heißt, Thread 1 hat den Bestand überprüft und dann den Bestand abgezogen. Zu diesem Zeitpunkt überprüft Thread 2 den Bestand erneut und zieht den Bestand ab Problem.

So lösen Sie das Redis-Coupon-Flash-Sale-Problem

Das Problem mit überverkauft liegt darin, dass nach der Überprüfung des Lagerbestands durch Bestellung 1 festgestellt wurde, dass es 1 war, aber bevor der Abzug vorgenommen wurde, überprüfte Thread 2 auch den Lagerbestand und stellte fest, dass es ebenfalls 1 war, und a Es wurde ein Abzug vorgenommen (in Szenarien mit hoher Parallelität)

So lösen Sie das Redis-Coupon-Flash-Sale-Problem

Dies führt zum Problem des Überverkaufs.

Für diese Art von Problemen mit hoher Parallelität ist die häufigste Lösung: Sperre ~ So lösen Sie das Redis-Coupon-Flash-Sale-Problem

Aber Sperren umfassen pessimistische Sperren und optimistische Sperren.

Pessimistisches Sperren bedeutet einfach: Ich denke, der Thread wird definitiv passieren, und dann nimmt jeder die Sperre vor der Operation. Nachdem Sie mit der Ausführung fertig sind, ist der nächste an der Reihe (serielle Ausführung)

Optimistisches Sperren: Es ist optimistisch (Es wird davon ausgegangen, dass Thread-Sicherheit niemals auftritt.) Solange vor jeder Datenänderung beurteilt wird, ob andere Threads die Daten geändert haben, um die Thread-Sicherheit sicherzustellen.

Pessimistisches Sperren ist relativ einfach, hier wird optimistisches Sperren implementiert. So lösen Sie das Redis-Coupon-Flash-Sale-Problem

Der Schlüssel zum optimistischen Sperren besteht darin, festzustellen, ob die durch die vorherige Abfrage erhaltenen Daten geändert wurden.

Warme Erinnerung: Die Daten in der Tabelle links sind alle Daten nach der Ausführung des Threads 1~

So lösen Sie das Redis-Coupon-Flash-Sale-Problem1. Versionsnummer Die Methode

besteht darin, nach jeder Änderung der Daten eine Versionsnummer hinzuzufügen und am Ende eine Where-Bedingung hinzuzufügen Die Versionsnummer stimmt mit der Version vor der Änderung überein. Auf diese Weise wird die Thread-Sicherheit erreicht Der Bestand ist der Bestand vor der Änderung

Code-Implementierung zur Lösung des Überverkaufsproblems:

In der letzten Analyse fügen wir beim Abzug des Bestandes eine Where-Bedingung hinzu, um zu bestimmen, ob der Bestand größer als 0 ist

package com.hmdp.service.impl;
import com.hmdp.dto.Result;
import com.hmdp.entity.SeckillVoucher;
import com.hmdp.entity.VoucherOrder;
import com.hmdp.mapper.VoucherOrderMapper;
import com.hmdp.service.ISeckillVoucherService;
import com.hmdp.service.IVoucherOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmdp.utils.RedisIdWorker;
import com.hmdp.utils.UserHolder;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.LocalDateTime;
/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 虎哥
 * @since 2021-12-22
 */
@Service
public class VoucherOrderServiceImpl extends ServiceImpl<VoucherOrderMapper, VoucherOrder> implements IVoucherOrderService {
    @Resource
    private ISeckillVoucherService iSeckillVoucherService;
    @Resource
    private RedisIdWorker redisIdWorker;
    @Override
    public Result seckillVoucher(Long voucherId) {
        //1.获取优惠券信息
        SeckillVoucher voucher = iSeckillVoucherService.getById(voucherId);
        //2.判断是否已经开始
        if (voucher.getBeginTime().isAfter(LocalDateTime.now())){
            Result.fail("秒杀尚未开始!");
        }
        //3.判断是否已经结束
        if (voucher.getEndTime().isBefore(LocalDateTime.now())){
            Result.fail("秒杀已经结束了!");
        }
        //4.判断库存是否充足
        if (voucher.getStock() < 1) {
            Result.fail("库存不充足!");
        }
        //5.扣减库存
        boolean success = iSeckillVoucherService.update()
                .setSql("stock = stock-1").eq("voucher_id",voucherId)
                .update();
        if (!success){
            Result.fail("库存不充足!");
        }
        //6. 创建订单
        VoucherOrder voucherOrder = new VoucherOrder();
        //6.1添加订单id
        Long orderId = redisIdWorker.nextId("order");
        voucherOrder.setId(orderId);
        //6.2添加用户id
        Long userId = UserHolder.getUser().getId();
        voucherOrder.setUserId(userId);
        //6.3添加优惠券id
        voucherOrder.setVoucherId(voucherId);
        save(voucherOrder);
        //7.返回订单id
        return Result.ok(orderId);
    }
}
Nach dem Login kopieren
//5.1扣减库存
boolean success = iSeckillVoucherService.update()
.setSql("stock = stock-1").eq("voucher_id" , voucherId).gt("stock" ,0)
.update();
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonSo lösen Sie das Redis-Coupon-Flash-Sale-Problem. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

So erstellen Sie den Redis -Clustermodus So erstellen Sie den Redis -Clustermodus Apr 10, 2025 pm 10:15 PM

Der Redis -Cluster -Modus bietet Redis -Instanzen durch Sharding, die Skalierbarkeit und Verfügbarkeit verbessert. Die Bauschritte sind wie folgt: Erstellen Sie ungerade Redis -Instanzen mit verschiedenen Ports; Erstellen Sie 3 Sentinel -Instanzen, Monitor -Redis -Instanzen und Failover; Konfigurieren von Sentinel -Konfigurationsdateien, Informationen zur Überwachung von Redis -Instanzinformationen und Failover -Einstellungen hinzufügen. Konfigurieren von Redis -Instanzkonfigurationsdateien, aktivieren Sie den Cluster -Modus und geben Sie den Cluster -Informationsdateipfad an. Erstellen Sie die Datei nodes.conf, die Informationen zu jeder Redis -Instanz enthält. Starten Sie den Cluster, führen Sie den Befehl erstellen aus, um einen Cluster zu erstellen und die Anzahl der Replikate anzugeben. Melden Sie sich im Cluster an, um den Befehl cluster info auszuführen, um den Clusterstatus zu überprüfen. machen

So löschen Sie Redis -Daten So löschen Sie Redis -Daten Apr 10, 2025 pm 10:06 PM

So löschen Sie Redis -Daten: Verwenden Sie den Befehl Flushall, um alle Schlüsselwerte zu löschen. Verwenden Sie den Befehl flushdb, um den Schlüsselwert der aktuell ausgewählten Datenbank zu löschen. Verwenden Sie SELECT, um Datenbanken zu wechseln, und löschen Sie dann FlushDB, um mehrere Datenbanken zu löschen. Verwenden Sie den Befehl del, um einen bestimmten Schlüssel zu löschen. Verwenden Sie das Redis-Cli-Tool, um die Daten zu löschen.

So lesen Sie Redis -Warteschlange So lesen Sie Redis -Warteschlange Apr 10, 2025 pm 10:12 PM

Um eine Warteschlange aus Redis zu lesen, müssen Sie den Warteschlangenname erhalten, die Elemente mit dem Befehl LPOP lesen und die leere Warteschlange verarbeiten. Die spezifischen Schritte sind wie folgt: Holen Sie sich den Warteschlangenname: Nennen Sie ihn mit dem Präfix von "Warteschlange:" wie "Warteschlangen: My-Queue". Verwenden Sie den Befehl LPOP: Wischen Sie das Element aus dem Kopf der Warteschlange aus und geben Sie seinen Wert zurück, z. B. die LPOP-Warteschlange: my-queue. Verarbeitung leerer Warteschlangen: Wenn die Warteschlange leer ist, gibt LPOP NIL zurück, und Sie können überprüfen, ob die Warteschlange existiert, bevor Sie das Element lesen.

So verwenden Sie den Befehl Redis So verwenden Sie den Befehl Redis Apr 10, 2025 pm 08:45 PM

Die Verwendung der REDIS -Anweisung erfordert die folgenden Schritte: Öffnen Sie den Redis -Client. Geben Sie den Befehl ein (Verbschlüsselwert). Bietet die erforderlichen Parameter (variiert von der Anweisung bis zur Anweisung). Drücken Sie die Eingabetaste, um den Befehl auszuführen. Redis gibt eine Antwort zurück, die das Ergebnis der Operation anzeigt (normalerweise in Ordnung oder -err).

So verwenden Sie Redis Lock So verwenden Sie Redis Lock Apr 10, 2025 pm 08:39 PM

Um die Operationen zu sperren, muss die Sperre durch den Befehl setNX erfasst werden und dann den Befehl Ablauf verwenden, um die Ablaufzeit festzulegen. Die spezifischen Schritte sind: (1) Verwenden Sie den Befehl setNX, um zu versuchen, ein Schlüsselwertpaar festzulegen; (2) Verwenden Sie den Befehl Ablauf, um die Ablaufzeit für die Sperre festzulegen. (3) Verwenden Sie den Befehl Del, um die Sperre zu löschen, wenn die Sperre nicht mehr benötigt wird.

So lesen Sie den Quellcode von Redis So lesen Sie den Quellcode von Redis Apr 10, 2025 pm 08:27 PM

Der beste Weg, um Redis -Quellcode zu verstehen, besteht darin, Schritt für Schritt zu gehen: Machen Sie sich mit den Grundlagen von Redis vertraut. Wählen Sie ein bestimmtes Modul oder eine bestimmte Funktion als Ausgangspunkt. Beginnen Sie mit dem Einstiegspunkt des Moduls oder der Funktion und sehen Sie sich die Codezeile nach Zeile an. Zeigen Sie den Code über die Funktionsaufrufkette an. Kennen Sie die von Redis verwendeten Datenstrukturen. Identifizieren Sie den von Redis verwendeten Algorithmus.

So verwenden Sie die Befehlszeile der Redis So verwenden Sie die Befehlszeile der Redis Apr 10, 2025 pm 10:18 PM

Verwenden Sie das Redis-Befehlszeilen-Tool (REDIS-CLI), um Redis in folgenden Schritten zu verwalten und zu betreiben: Stellen Sie die Adresse und den Port an, um die Adresse und den Port zu stellen. Senden Sie Befehle mit dem Befehlsnamen und den Parametern an den Server. Verwenden Sie den Befehl Hilfe, um Hilfeinformationen für einen bestimmten Befehl anzuzeigen. Verwenden Sie den Befehl zum Beenden, um das Befehlszeilenwerkzeug zu beenden.

So lösen Sie Datenverlust mit Redis So lösen Sie Datenverlust mit Redis Apr 10, 2025 pm 08:24 PM

Zu den Ursachen für Datenverluste gehören Speicherausfälle, Stromausfälle, menschliche Fehler und Hardwarefehler. Die Lösungen sind: 1. Speichern Sie Daten auf Festplatten mit RDB oder AOF Persistenz; 2. Kopieren Sie auf mehrere Server, um eine hohe Verfügbarkeit zu erhalten. 3. Ha mit Redis Sentinel oder Redis Cluster; 4. Erstellen Sie Schnappschüsse, um Daten zu sichern. 5. Implementieren Sie Best Practices wie Persistenz, Replikation, Schnappschüsse, Überwachung und Sicherheitsmaßnahmen.

See all articles