Problembeschreibung:
Eine E-Commerce-Plattform bringt ein neues Mobiltelefon auf den Markt. Jede Person ist auf den Kauf von 2 Einheiten beschränkt, und es wird erwartet, dass es eine Parallelität von 10 W gibt. Wenn der Lagerbestand in diesem Fall abgezogen wird, wird garantiert, dass er nicht überverkauft wird
Lösung 1
Verwenden Sie den Datenbanksperrmechanismus, um die Sperre aufzuzeichnen und dann zu betreiben
SELECT * from goods where ID =1 for update; UPDATE goods set stock = stock - 1;
Verwenden Sie die exklusive Sperre, um den Parallelbetrieb in den seriellen Betrieb umzuwandeln, aber die Leistung und Benutzererfahrung dieser Lösung sind schlecht
Lösung 2
Verwenden Sie Redis, um verteilte Sperren zu implementieren.
Verwenden Sie den Befehl setnx (wenn der Schlüssel nicht vorhanden ist, erstellen und legen Sie den Wert fest und geben Sie 1 zurück. Wenn der Schlüssel vorhanden ist, wird 0 zurückgegeben). Erhalten Sie die Sperre. In der Geschäftslogik können wir durch ein solches Schema arbeiten
Jedis client = jedisPool.getResource(); while(client.setnx("lock",String.valueOf(System.currentTimeMillis())) == 0){ Thread.sleep(10000); } //coding here client.del("lock")
Schema 2 Fortgeschritten
Unter Berücksichtigung des Deadlock-Problems, das heißt, nachdem fertig A die Sperre erhält, wird es geht aus, was dazu führt, dass die Sperre nicht freigegeben werden kann. Der Befehl ruft den Zeitstempel der Sperre ab, ermittelt anhand dessen das Zeitlimit und gibt ihn frei
Long TIMEOUT_SECOUND = 120000L; Jedis client = jedisPool.getResource(); while(client.setnx("lock",String.valueOf(System.currentTimeMillis())) == 0){ Long lockTime = Long.valueOf(client.get("lock")); if (lockTime!=null && System.currentTimeMillis() > lockTime+TIMEOUT_SECOUND) { client.del("lock"); } Thread.sleep(10000); } ........................... ........................... client.del("lock")
Option 2 verstärkt
Im Algorithmus von Option 2 können Sie den Thread-Funktionscode
Long TIMEOUT_SECOUND = 120000L; String featureCode = "machine01"; Jedis client = jedisPool.getResource(); while(client.setnx("lock",featureCode+":"+String.valueOf(System.currentTimeMillis())) == 0){ Long lockTime = Long.valueOf(client.get("lock").substring(9)); if (lockTime!=null && System.currentTimeMillis() > lockTime+TIMEOUT_SECOUND) { client.del("lock"); } Thread.sleep(10000); } ........................... ........................... if (featureCode.equals(client.get("lock").substring(0, 8))) { client.del("lock"); }
buchstabieren, um sicherzustellen, dass die Sperre in Nicht-Timeout-Situationen nur freigegeben werden kann, indem Sie den gesperrten Thread freigeben im Zeitstempel des Wertes Weitere technische Artikel zu Redis finden Sie in der Spalte Redis-Tutorial zum Lernen!
Das obige ist der detaillierte Inhalt vonWie Redis verteilte Transaktionen implementiert. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!