Heim >Datenbank >Redis >Erfahren Sie mehr über Transaktionen in Redis

Erfahren Sie mehr über Transaktionen in Redis

青灯夜游
青灯夜游nach vorne
2021-04-13 10:57:321938Durchsuche

Dieser Artikel vermittelt Ihnen ein detailliertes Verständnis der Transaktionen in Redis. Es hat einen gewissen Referenzwert. Freunde in Not können sich darauf beziehen. Ich hoffe, es wird für alle hilfreich sein.

Erfahren Sie mehr über Transaktionen in Redis

【Verwandte Empfehlungen: Redis-Video-Tutorial

Verwandte Befehle

immer OK.
Befehl Format Funktion Ergebnisse zurückgeben
WATCH WATCH-Taste [ Schlüssel...] Markieren Sie die angegebenen Schlüssel als Überwachungsstatus als Bedingung für die TransaktionsausführungKeys标记为监测态,作为事务执行的条件 always OK.
UNWATCH UNWATCH 清除事务中Keys监测态,如果调用了EXEC or DISCARD,则没有必要再手动调用UNWATCH always OK.
MULTI MULTI 显式开启redis事务,后续commands将排队,等候使用EXEC进行原子执行 always OK.
EXEC EXEC 执行事务中的commands队列,恢复连接状态。如果WATCH在之前被调用,只有监测中的Keys没有被修改,命令才会被执行,否则停止执行(详见下文,CAS机制 成功: 返回数组 —— 每个元素对应着原子事务中一个 command的返回结果;
失败: 返回NULLRuby 返回`nil`);
DISCARD DISCARD 清除事务中的commands队列,恢复连接状态。如果WATCH在之前被调用,释放 监测中的Keys
UNWATCH🎜🎜 🎜🎜 UNWATCH🎜🎜🎜Löschen Sie den Überwachungsstatus von Schlüsseln in der Transaktion. Wenn 🎜EXEC🎜 oder 🎜DISCARD🎜 aufgerufen wird, ist es nicht erforderlich, 🎜UNWATCH🎜🎜 manuell aufzurufen 🎜 immer OK.🎜🎜🎜🎜🎜MULTI🎜🎜🎜🎜MULTI🎜🎜🎜Explizit öffnen Sie die Redis-Transaktion, nachfolgende Befehle werden in die Warteschlange gestellt und warten. Verwenden Sie 🎜EXEC🎜 für die atomare Ausführung 🎜🎜immer OK.🎜🎜🎜🎜🎜EXEC🎜🎜🎜🎜EXEC🎜🎜🎜Führen Sie die Befehle-Warteschlange in der Transaktion aus und stellen Sie den Verbindungsstatus wieder her. Wenn 🎜WATCH🎜 zuvor aufgerufen wurde, wird der Befehl nur ausgeführt, wenn die Schlüssel in Überwachung nicht geändert wurden, andernfalls wird die Ausführung gestoppt (Einzelheiten siehe unten, CAS-Mechanismus) 🎜🎜🎜Erfolg: 🎜 Rückgabearray – jedes Element entspricht dem Rückgabeergebnis eines Befehls in der atomaren Transaktion;
🎜Fehler: 🎜 Rückgabe NULL(Ruby gibt `nil` zurück); / Stellen Sie im Transaktionscode>Warteschlange den Verbindungsstatus wieder her. Wenn 🎜WATCH🎜 zuvor aufgerufen wurde, Tasten loslassen Tasten in Monitor🎜🎜immer OK.🎜🎜🎜🎜

Hinweis:

------MULTI, EXEC, DISCARD sind explizitGemeinsame Befehle zum Öffnen und Steuern von Transaktionen können mit BEGAIN, COMMIT, ROLLBACK in der relationalen Datenbank verglichen werden >( Tatsächlich ist die Lücke riesig); /code> Probleme mit /code> und Phantom-Lesung (einfach als Sperren von Schlüssel verstanden); - 1">Redis-TransaktionMULTI,EXEC,DISCARD才是显式开启并控制事务的常用命令,可类比关系型数据库中的  BEGAIN,COMMIT,ROLLBACK(事实上,差距很大);

------WATCH命令的使用是为了解决 事务并发 产生的不可重复读幻读的问题(简单理解为给Key加锁);


Redis事务

MULTI, EXEC, DISCARD and WATCH 是Redis事务的基础。用来显式开启并控制一个事务,它们允许在一个步骤中执行一组命令。并提供两个重要的保证:

  • 事务中的所有命令都会被序列化并按顺序执行。在执行Redis事务的过程中,不会出现由另一个客户端发出的请求。这保证 命令队列 作为一个单独的原子操作被执行。
  • 队列中的命令要么全部被处理,要么全部被忽略。EXEC命令触发事务中所有命令的执行,因此,当客户端在事务上下文中失去与服务器的连接,
  • 如果发生在调用MULTI命令之前,则不执行任何commands
  • 如果在此之前EXEC命令被调用,则所有的commands都被执行。

同时,redis使用AOF(append-only file),使用一个额外的write操作将事务写入磁盘。如果发生宕机,进程奔溃等情况,可以使用redis-check-aof tool 修复append-only file,使服务正常启动,并恢复部分操作。


用法

使用MULTI命令显式开启Redis事务。 该命令总是以OK回应。此时用户可以发出多个命令,Redis不会执行这些命令,而是将它们排队EXEC被调用后,所有的命令都会被执行。而调用DISCARD可以清除事务中的commands队列退出事务

  • 以下示例以原子方式,递增键foo和bar。
>MULTI
OK
>INCR foo
QUEUED
>INCR bar
QUEUED
>EXEC
1)(整数)1
2)(整数)1

从上面的命令执行中可以看出,EXEC返回一个数组其中每个元素都是事务中单个命令的返回结果,而且顺序与命令的发出顺序相同。 当Redis连接处于MULTI请求的上下文中时,所有命令将以字符串QUEUED从Redis协议的角度作为状态回复发送)作为回复,并在命令队列中排队。只有EXEC被调用时,排队的命令才会被执行,此时才会有真正的返回结果


事务中的错误

事务期间,可能会遇到两种命令错误:

  • 在调用EXEC命令之前出现错误(COMMAND排队失败)。
  • 例如,命令可能存在语法错误(参数数量错误,错误的命令名称...);
  • 或者可能存在某些关键条件,如内存不足的情况(如果服务器使用maxmemory指令做了内存限制)。

客户端会在EXEC调用之前检测第一种错误。 通过检查排队命令的状态回复(***注意:这里是指排队状态回复,而不是执行结果***),如果命令使用QUEUED进行响应,则它已正确排队,否则Redis将返回错误。如果排队命令时发生错误,大多数客户端将中止该事务并清除命令队列。然而:

  • Redis 2.6.5之前,这种情况下,在EXEC命令调用后,客户端会执行命令的子集(成功排队的命令)而忽略之前的错误。
  • Redis 2.6.5开始,服务端会记住在累积命令期间发生的错误,当EXEC命令调用时,将拒绝执行事务,并返回这些错误,同时自动清除命令队列
  • 示例如下:
>MULTI
+OK
>INCR a b c
-ERR wrong number of arguments for 'incr' command

这是由于INCR命令的语法错误,将在调用EXEC之前被检测出来,并终止事务(version2.6.5+)。

  • 在调用EXEC命令之后出现错误。
  • 例如,使用错误的值对某个key执行操作(如针对String值调用List操作)

EXEC命令执行之后发生的错误并不会被特殊对待即使事务中的某些命令执行失败,其他命令仍会被正常执行MULTI, EXEC, DISCARD und WATCH sind die Basis der Redis-Transaktion. Sie werden zum expliziten Starten und Steuern einer Transaktion verwendet und ermöglichen die Ausführung einer Reihe von Befehlen in einem Schritt. Und bietet zwei wichtige Garantien:

  • Alle Befehle in der Transaktion werden serialisiert und der Reihe nach ausgeführt. Während der Ausführung einer Redis-Transaktion erfolgt keine Anfrage eines anderen Clients. Dadurch wird sichergestellt, dass die Befehlswarteschlange als einzelne atomare Operation ausgeführt wird.
  • Alle Befehle in der Warteschlange werden entweder verarbeitet oder ignoriert. Der EXEC-Befehl löst die Ausführung aller Befehle in der Transaktion aus. Wenn der Client also im Kontext einer Transaktion die Verbindung zum Server verliert,
  • wenn dies geschieht, bevor der MULTI-Befehl aufgerufen wird, gibt es keinen Befehle
  • werden ausgeführt. code>;
  • Wenn der EXEC-Befehl vorher aufgerufen wird, werden alle Befehle ausgeführt.
🎜Gleichzeitig verwendet Redis AOF (append-only Datei🎜 a>), wobei ein zusätzlicher Schreibvorgang verwendet wird, um die Transaktion auf die Festplatte zu schreiben. Wenn es zu einer Ausfallzeit, einem Prozessabsturz usw. kommt, können Sie das Redis-Check-Aof-Tool verwenden, um die Nur-Anhänge-Datei zu reparieren, sodass der Dienst normal starten und einige Vorgänge wieder aufnehmen kann. 🎜

Verwendung

🎜Verwenden Sie den Befehl MULTI, um die Redis-Transaktion explizit zu öffnen. Dieser Befehl antwortet immer mit OK. Benutzer können zu diesem Zeitpunkt mehrere Befehle ausgeben, aber Redis führt diese Befehle nicht aus, sondern stellt sie in die Warteschlange. Nach dem Aufruf von EXEC werden alle Befehle ausgeführt. Der Aufruf von DISCARD kann die Befehlswarteschlange in der Transaktion löschen und die Transaktion verlassen. 🎜
  • Das folgende Beispiel erhöht atomar die Tasten foo und bar.
>MULTI
+OK
>SET a 3
+QUEUED
>LPOP a
+QUEUED
>EXEC
*2
+OK
-ERR Operation against a key holding the wrong kind of value
🎜Wie aus der obigen Befehlsausführung ersichtlich ist, gibt EXEC ein Array zurück, dessen jedes Element in der Transaktion enthalten ist Die von einem einzelnen Befehl zurückgegebenen Ergebnisse in derselben Reihenfolge, in der die Befehle ausgegeben wurden. Wenn eine Redis-Verbindung im Kontext einer MULTI-Anfrage steht, werden alle Befehle mit STRING QUEUED beantwortet (🎜aus Sicht des Redis-Protokolls als Statusantwort gesendet🎜). ) und in der Warteschlange in Befehlswarteschlange. Erst wenn EXEC aufgerufen wird, werden die in der Warteschlange befindlichen Befehle ausgeführt und es gibt dann echte Rückgabeergebnisse. 🎜

Fehler in Transaktionen

🎜🎜Während einer Transaktion können zwei Befehlsfehler auftreten: 🎜🎜
  • 🎜Beim Aufruf Ein Fehler ist vor dem Befehl EXEC aufgetreten (COMMAND konnte nicht in die Warteschlange gestellt werden). 🎜
  • Zum Beispiel kann der Befehl Syntaxfehler haben (falsche Anzahl von Parametern, falscher Befehlsname...);
  • oder es können einige Schlüsselbedingungen, wie z. B. unzureichender Speicher (wenn der Server die maxmemory-Direktive verwendet, um ein Speicherlimit festzulegen).
🎜🎜Der Client erkennt den ersten Fehler🎜, bevor er EXEC aufruft. Durch Überprüfen der Statusantwort des Befehls in der Warteschlange (***Hinweis: Dies bezieht sich auf die Statusantwort des in der Warteschlange, nicht auf den Ausführungsergebnis***), wenn der Befehl mit <code>QUEUED antwortet, wird er korrekt in die Warteschlange gestellt, andernfalls gibt Redis einen Fehler zurück. Wenn beim Einreihen eines Befehls in die Warteschlange ein Fehler auftritt, brechen die meisten Clients die Transaktion ab und leeren die Befehlswarteschlange. Allerdings: 🎜
  • Vor Redis 2.6.5, in diesem Fall, nachdem der Befehl EXEC aufgerufen wurde, führt der Client eine Teilmenge des Befehls aus ( erfolgreich in die Warteschlange gestellte Befehle), während frühere Fehler ignoriert werden.
  • Ab Redis 2.6.5 merkt sich der Server Fehler, die während der Anhäufung von Befehlen aufgetreten sind. Wenn der Befehl EXEC aufgerufen wird, Die Ausführung der Transaktion wird abgelehnt, diese Fehler werden zurückgegeben und die Befehlswarteschlange wird automatisch geleert.
  • Das Beispiel sieht wie folgt aus:
> SET foo 1
OK
> MULTI
OK
> INCR foo
QUEUED
> DISCARD
OK
> GET foo
"1"
🎜🎜Dies liegt am Syntaxfehler des Befehls INCR, der vor dem Aufruf von EXEC Erkennen Sie es und beenden Sie die Transaktion (Version 2.6.5+). 🎜
  • 🎜Nach dem Aufruf des Befehls EXEC ist ein Fehler aufgetreten. 🎜
  • Zum Beispiel die Verwendung von falscher Wert, um eine Operation für einen Schlüssel auszuführen (z. B. den Aufruf von für einen <code>String Code>Wertliste-Operation)
🎜🎜Fehler, die nach der Ausführung des Befehls EXEC auftreten, werden nicht speziell behandelt🎜: Auch wenn einige Befehle ausgeführt werden in der Transaktion werden ausgeführt. Wenn dies fehlschlägt, werden andere Befehle weiterhin normal ausgeführt. 🎜
  • 示例如下:
>MULTI
+OK
>SET a 3
+QUEUED
>LPOP a
+QUEUED
>EXEC
*2
+OK
-ERR Operation against a key holding the wrong kind of value
  • EXEC返回一个包含两个元素的字符串数组,一个元素是OK,另一个是-ERR……
  • 能否将错误合理的反馈给用户这取决于客户端library(如:Spring-data-redis.redisTemplate)的自身实现。
  • 需要注意的是,即使命令失败,队列中的所有其他命令也会被处理----Redis不会停止命令的处理

Redis事务不支持Rollback(重点

事实上Redis命令在事务执行时可能会失败,但仍会继续执行剩余命令而不是Rollback(事务回滚)。如果你使用过关系数据库,这种情况可能会让你感到很奇怪。然而针对这种情况具备很好的解释:

  • Redis命令可能会执行失败,仅仅是由于错误的语法被调用(命令排队时检测不出来的错误),或者使用错误的数据类型操作某个Key: 这意味着,实际上失败的命令都是编程错误造成的,都是开发中能够被检测出来的,生产环境中不应该存在。(这番话,彻底甩锅,“都是你们自己编程错误,与我们无关”。)
  • 由于不必支持Rollback,Redis内部简洁并且更加高效。

如果错误就是发生了呢?”这是一个反对Redis观点的争论。然而应该指出的是,通常情况下,回滚并不能挽救编程错误。鉴于没有人能够挽救程序员的错误,并且Redis命令失败所需的错误类型不太可能进入生产环境,所以我们选择了不支持错误回滚(Rollback)这种更简单快捷的方法。


清除命令队列

DISCARD被用来中止事务。事务中的所有命令将不会被执行,连接将恢复正常状态。

> SET foo 1
OK
> MULTI
OK
> INCR foo
QUEUED
> DISCARD
OK
> GET foo
"1"

更多编程相关知识,请访问:编程视频!!

Das obige ist der detaillierte Inhalt vonErfahren Sie mehr über Transaktionen in Redis. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.cn. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen