Heim  >  Artikel  >  Backend-Entwicklung  >  Sperren und Entsperren von PHP Redis

Sperren und Entsperren von PHP Redis

不言
不言Original
2018-07-06 16:59:503336Durchsuche

Dieser Artikel stellt hauptsächlich das Sperren und Entsperren von PHP Redis vor, das einen gewissen Referenzwert hat. Jetzt kann ich es mit allen teilen, die es brauchen.

PHP+Redis realisiert den Sperr- und Entsperrvorgang

Geschäftshintergrund: Bei Raumschach- und Kartenspielen werden Sperren benötigt, um ein unsauberes Lesen von Redis-Daten zu verhindern, das durch gleichzeitige Vorgänge verursacht wird, beispielsweise durch das Hinzufügen der Aktion eines Benutzers, der den Raum betritt:

Sperren und Entsperren von PHP Redis

Unter gleichzeitigen Bedingungen erhalten RoomUsers Dirty Reads.


Lösung: Sperren Sie den Raum, um jedes Mal einen Raum zu implementieren Es darf nur ein Client betrieben werden, und andere gleichzeitige Clients warten. Das heißt, es gibt mehrere Redis-Sperrmethoden: incr, set, setnx, hSetnx, Sie können sich auf diesen Artikel beziehen: Mehrere Implementierungen der Redis-Sperre


Hier verwende ich die Set-Methode

$roomId = $_GET['roomId'];
$user = $_GET['user'];             // '张三'
$key = "LockRoom:{$roomId}";
$value = $roomId.uniqid();
$ex = 3;
// 如果 $key 不存在的话,就设置 $key 的值为 $value,且有效期为 3s; 
// return TRUE / FALSE
while(true){
    $res  = $this->redis->set($key, $value, ['nx', 'ex' => $ex]);
    if($res) { break; }
    usleep(5000);
}

// 将用户添加进房间
$roomUsers = $this->redis->get("Room:{$roomId}:Users"); // ['李四', '王五']
$roomUsers[] = $user;
$this->redis->set("Room:{$roomId}:Users", $roomUsers); // ['李四', '王五', '张三']

Unlock

: Natürlich müssen Sie es nach dem Vorgang entsperren.

Zum Entsperren müssen Sie den Schlüssel löschen Löschen kann nicht direkt verwendet werden, da davon ausgegangen wird, dass Client01 die Sperre erhalten und den Benutzer zum Raum hinzugefügt hat. Zu diesem Zeitpunkt erhält Client02 auch die Sperre und setzt 3S Schließt den Vorgang ab und löscht den Schlüssel, wird die von client02 festgelegte Sperre gelöscht.
Es wird empfohlen, zum Löschen den Lua-Code zu verwenden.

// 将用户添加进房间
$roomUsers = $this->redis->get("Room:{$roomId}:Users"); // ['李四', '王五']
$roomUsers[] = $user;
$this->redis->set("Room:{$roomId}:Users", $roomUsers); // ['李四', '王五', '张三']

// lua 脚本解锁
// 先判断 key的值是否为 value, TRUE 才会删除, 所以 $value 的设计要有随机唯一性
$script = 'if redis.call("get",KEYS[1]) == ARGV[1]
then
    return redis.call("del",KEYS[1])
else
    return 0
end ';
$this->redis->eval($script, array($key , $value), 1);
Weitere Informationen finden Sie auch in diesem Artikel: Die richtige Haltung zum Entsperren der Redis-Sperre
Es gibt auch ein Dokument über die PHP-Bedienung von Redis: PhpRedis enthält Erklärungen zu set() und eval()-Funktionen

Hinweis: Bei Verwendung von Lua-Skript muss php.ini Systemfunktionen wie shell_exec() öffnen

Der obige Code dient nur als Referenz! !

Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, er wird für das Studium aller hilfreich sein. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website.

Verwandte Empfehlungen:

Anmerkungen zu Methoden und Parametern des PHP-Betriebs von Beanstalkd

Intranet-Penetrationsanwendung Spike implementiert durch PHP Refactoring abgeschlossen

Das obige ist der detaillierte Inhalt vonSperren und Entsperren von PHP Redis. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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