Ich habe den Rails Guide gelesen und war neugierig, also habe ich ihn tatsächlich berührt. Das Memo.
Wenn Herr A und Herr B denselben Datensatz in der Anwendung bearbeiten und Herr A genau zum gleichen Zeitpunkt auf denselben Datensatz zugreift, aktualisiert Herr A den Datensatz und dann Herr B aktualisiert, bearbeitet Herr B den Inhalt von Herrn A. Es wird ohne Bestätigung überschrieben. Wenn es sich um ein Update mit demselben Attribut handelt und es sich um ein anderes Attribut handelt, wird die Bearbeitung zurückgespult, was keine gute Situation ist.
Active Record bietet lock_version für dieses Problem. lock_version fügt der Tabelle eine Spalte hinzu, die als Bearbeitungsverlaufsanzahl für diese Instanz dient und auf deren Wert verweist Wenn Sie lock_version verwenden, können Sie in den oben genannten Fällen einen Fehler generieren.
Erstellen Sie dazu eine Spalte mit dem Namen lock_version in der Tabelle.
t.integer :lock_version, default: 0
p1 = Memo.find(1)
p2 = Memo.find(1)
# => #<Memo id: 1, text: "hello", lock_version: 0>
Natürlich ist lock_version 0, wenn es noch aufgerufen wird Aktualisieren Sie dann p1.
p1.update(text:'good bye')
# => #<Memo id: 1, text: "good bye", lock_version: 1>
SQL
(0.3ms) BEGIN
Memo Update (13.4ms) UPDATE `memos` SET `text` = 'good bye', `lock_version` = 1 WHERE `memos`.`id` = 1 AND `memos`.`lock_version` = 0
(3.9ms) COMMIT
look_version wurde in 1 umgeschrieben. Sie können auch sehen, dass die SQL-Bedingung für die Aktualisierung "lock_version = 0" lautet. Als nächstes aktualisieren wir p2. Die lock_version der p2-Instanz bleibt 0, da sie nicht neu geladen wurde.
p2.update(text:'say hello')
# => ActiveRecord::StaleObjectError (Attempted to update a stale object: Memo.)
SQL
(0.7ms) BEGIN
Memo Update (1.0ms) UPDATE `memos` SET `text` = 'say hello', `lock_version` = 1 WHERE `memos`.`id` = 1 AND `memos`.`lock_version` = 0
(2.4ms) ROLLBACK
Sie erhalten einen Fehler. Ich glaube nicht, dass SQL selbst ausgegeben wird, selbst wenn ein Fehler ausgeführt wird. Es scheint also, dass ein Fehler mit dem Auslöser zurückgegeben wird, dass es keine Zeile gibt, die die Schienen beeinflusst. Ich werde die Quelle dieses Mal nicht lesen. Wenn Sie sie lesen, teilen Sie sie bitte mit!
Wie bei RailsApi fügen wir lock_version als versteckten Parameter in das Formular ein. Ohne diese Funktion kann das Backend lock_version nicht vergleichen und generiert keinen Fehler.
<input type="hidden" value="2" name="memo[lock_version]" id="memo_lock_version">
Ich habe das oben Gesagte hinzugefügt, zwei Registerkarten geöffnet, um denselben Datensatz zu bearbeiten und jeweils zu aktualisieren, und derjenige, der später aktualisiert hat, hat sicher einen Fehler erhalten.
Danach behandeln wir den Fehler wie in Rails Api beschrieben. Es gibt verschiedene Möglichkeiten, damit umzugehen.
――Wenn zwei Personen unterschiedliche Attribute bearbeitet haben, aktualisieren Sie diese in der angegebenen Reihenfolge. Wenn sie dasselbe Attribut bearbeiten, zeigen Sie es auf dem Bildschirm an und bestätigen Sie dies mit dem Benutzer.
Und. Ich frage mich, ob dieser Bereich davon abhängt, wie die Daten in der App verwendet werden.
Ich habe es in der Praxis nicht verwendet, daher würde ich mich freuen, wenn Sie etwas wie "Ich mache das in meinem Haus!" Teilen könnten!
Rails Guide What is Optimistic Locking
Recommended Posts