Die Dokumentation für Transaktionen sagt:Redis: Warum ersetzt Lua Scripting die Transaktionen?
„wir verbitten können und schließlich entfernen Transaktionen“ und „alles, was Sie mit einer Redis Transaktion tun können, können Sie auch mit einem Skript tun“
http://redis.io/topics/transactions
Aber tut es? Ich sehe ein Problem damit.
Innerhalb einer Transaktion können Sie mehrere Variablen beobachten, diese Variablen lesen, und basierend auf dem eindeutigen Status dieser Variablen können Sie vor dem Aufruf von EXEC eine komplett andere Reihe von Schreibvorgängen vornehmen. Wenn irgendetwas in der Zwischenzeit den Zustand dieser Variablen beeinträchtigt, führt EXEC die Transaktion nicht aus. (Dies ermöglicht es Ihnen, es erneut zu versuchen. Dies ist ein perfektes Transaktionssystem.)
Ein EVAL-Skript lässt Sie das nicht tun. Gemäß der Dokumentation auf dieser Seite:
„Scripts als reine Funktionen ... Das Skript wertet immer die gleichen Redis Schreibbefehle mit den gleichen Argumenten bei gleichen Eingabedaten Satz Operationen des Skripts nicht. abhängig von irgendwelchen versteckten (nicht explizite) Informationen oder Status, die sich ändern können, wie Skript Ausführung fährt oder zwischen verschiedenen Ausführungen des Skripts, noch kann es von jeder externen Eingabe von E/A-Geräten abhängen. "
Das Problem, das ich mit EVAL sehen ist, dass Sie nicht den Status dieser Variablen innerhalb des Skripts bekommen und einen einzigartigen Satz von Schreibvorgängen auf Basis machen über den Zustand dieser Variablen. Nochmals: "Das Skript wertet immer die gleichen Redis-Schreibbefehle mit den gleichen Argumenten bei gleichem Eingabedatensatz aus." Daher werden die resultierenden Schreibvorgänge bereits bestimmt (zwischengespeichert aus dem ersten Durchlauf), und das EVAL-Skript kümmert sich nicht darum, was die GET-Werte innerhalb des Skripts sind. Sie können GET nur für diese Variablen ausführen, bevor Sie EVAL aufrufen, und diese Variablen dann an das EVAL-Skript übergeben. Hier ist das Problem: Sie haben jetzt ein Problem mit der Atomarität zwischen dem Aufruf von GET und dem Aufruf von EVAL.
Mit anderen Worten, alle Variablen, die Sie eine WATCH für eine Transaktion gemacht hätten, müssen Sie im Falle von EVAL stattdessen diese Variablen holen und sie dann an das EVAL-Skript übergeben. Da die atomare Natur des Skripts erst beim Start des Skripts garantiert wird und Sie diese Variablen vor dem Aufruf von EVAL abrufen müssen, um das Skript zu starten, bleibt eine Öffnung, bei der sich der Status dieser Variablen zwischen dem GET ändern und übergeben kann zu EVAL. Daher haben Sie die Atomaritätsgarantie, die Sie mit WATCH haben, nicht mit EVAL für einen sehr wichtigen Anwendungsfall.
Warum wird von ablehnenden Transaktionen gesprochen, wenn dadurch wichtige Redis-Funktionen verloren gehen? Oder gibt es tatsächlich eine Möglichkeit, dies mit EVAL-Skripten zu tun, die ich noch nicht verstehe? Oder sind Features geplant, die das für EVAL lösen können? (Hypothetisches Beispiel: Wenn WATCH mit EVAL genauso wie WATCH mit EXEC arbeitet, könnte das funktionieren.)
Gibt es dafür eine Lösung? Oder muss ich verstehen, dass Redis auf lange Sicht nicht absolut sicher ist?
Wenn das, was Sie sagen, auf praktischer Erfahrung basiert, dann ist das gut! Es übertrumpft meine Interpretation der Dokumentation: "Das Skript wertet immer dieselben Redis-Schreibbefehle mit den gleichen Argumenten bei gleichem Eingabedatensatz aus." Für mich bedeutet das, dass ein Caching-Mechanismus läuft, so dass das Skript beim zweiten Mal nicht einmal ausgewertet wird. Es nimmt nur eine Reihe von Schreibvorgängen mit der gleichen Eingabe an. Klingt nicht deterministisch. Aber wenn Sie tatsächliche Erfahrung damit haben, schiebe ich auf Ihre Expertise und ich danke Ihnen für Ihre Antwort. – OCDev
Auch über mein hypothetisches Beispiel sprach ich über ein hypothetisches Feature, bei dem WATCH * außerhalb * von EVAL und * vor * EVAL verwendet werden könnte. (Ein neues Feature, bei dem sich EVAL in diesem Sinne wie EXEC verhält.) Auf diese Weise könnten die GETs in Vorbereitung darauf durchgeführt werden, sie an EVAL weiterzuleiten und sich nicht darum kümmern zu müssen, dass sie sich ändern. (Moot Punkt obwohl wenn innerhalb von EVAL ist schließlich deterministisch.) Nochmals vielen Dank. :) – OCDev
Was passiert, wenn Redis DB Server zwischen Transaktion (MULTI/EXEC) und Eval? Nehmen Sie an, dass einige Befehle wie POP/PUSH ausgeführt wurden ... und bevor einige weitere Befehle ausgeführt wurden. –