Sollte ein einzelner Fehler eine Massenoperation fehlschlagen?


11

In der API, an der ich arbeite, gibt es einen Massenlöschvorgang, der ein Array von IDs akzeptiert:

["1000", ..., "2000"]

Es stand mir frei, den Löschvorgang nach eigenem Ermessen zu implementieren, daher habe ich beschlossen, die gesamte Transaktion durchzuführen: Wenn eine einzelne ID ungültig ist, schlägt die gesamte Anforderung fehl. Ich werde dies den strengen Modus nennen.

try{
savepoint = conn.setSavepoint();

for(id : IDs)
    if( !deleteItem(id) ){
        conn.rollback(savepoint);
        sendHttp400AndBeDoneWithIt();
        return;
    }

conn.commit();
}

Die Alternative (an anderer Stelle in unserer Software-Suite implementiert) besteht darin, im Backend das zu tun, was wir können, und Fehler in einem Array zu melden. Dieser Teil der Software behandelt weniger Anforderungen, sodass die Antwort nicht zu einem gigantischen Array wird ... theoretisch.


Ein kürzlich aufgetretener Fehler auf einem ressourcenarmen Server hat mich veranlasst, den Code erneut zu überprüfen, und jetzt stelle ich meine ursprüngliche Entscheidung in Frage - diesmal bin ich jedoch eher von geschäftlichen Anforderungen als von Best Practices motiviert. Wenn beispielsweise die gesamte Anforderung fehlschlägt, muss der Benutzer es erneut versuchen. Wenn jedoch mehrere Elemente gelöscht werden, kann der Benutzer die Aktion beenden und dann einen Administrator bitten, den Rest zu erledigen (während ich an der Behebung des Fehlers arbeite !). Dies wäre der zulässige Modus.

Ich habe versucht, online nach einer Anleitung zu suchen, bin aber mit leeren Händen aufgetaucht. Also komme ich zu Ihnen: Was wird von Massenoperationen dieser Art am meisten erwartet? Sollte ich mich strikt an mehr halten oder sollte ich freizügiger sein?


9
Es hängt davon ab, ob. Was kostet es, wenn etwas nicht gelöscht wird, wenn es sein sollte? (Kosten werden definiert als schlechte Daten, Kopfschmerzen, unerwünschtes Verhalten, die Zeit, die ein Administrator benötigt, um sie zu beheben usw.) Ist das akzeptabel? Wenn Sie mit den Konsequenzen leben können, wenn Sie nicht alles versagen, dann machen Sie es. Wenn es zu viel Problem verursachen würde, tun Sie es nicht. Sie kennen Ihre Software und die Konsequenzen und müssen daher ein Urteil fällen.
Becuzz

1
@Becuzz Die Kosten wären, wenn der Benutzer ein oder zwei Reste bemerkt und ein Ticket darüber öffnet. Die aktuelle Situation ist "omg delete is defekt". Glücklicherweise ist der Benutzer den Flur entlang, so dass es diesmal kein allzu großes Problem ist. Der Punkt ist, Ich mag das tun , richtig , was , wann immer möglich, und mit einem 10+ Jahre alten Codebasis, Gott weiß einige Dinge stehen kann es richtig gemacht werden
rath

Ich denke, das hängt auch davon ab, ob Sie Skalierbarkeit wünschen oder nicht. Wenn Sie nicht vorhaben, viele Ausweise zu haben, sollte dies nicht allzu wichtig sein. Wenn Sie beabsichtigen, eine Million IDs zu haben, oder noch besser, nicht sicher sind, ob dies nicht der Fall ist, können Sie eine Stunde damit verbringen, IDs zu löschen, um sie aufgrund einer ungültigen ID vollständig zurückzusetzen.
imnota4

1
@ imnota4 Ein ausgezeichneter Punkt, den ich nicht berücksichtigt hatte. Die Benutzeroberfläche beschränkt die Anforderung auf maximal etwa 250, das Backend unterliegt jedoch keinen Einschränkungen. Darf ich Sie bitten, Ihren Kommentar als Antwort erneut zu veröffentlichen?
Rath

1
Der zulässige Modus erleichtert Administratoren auch die Arbeit, da sie den Fehler nicht mit allen ID-Stapeln reproduzieren müssen. Es kann auch nützlich sein, in der Antwort die Ursache jedes Fehlers anzugeben. Wenn man sich die Ursache ansieht, kann es für den Endbenutzer möglich sein, sie zu lösen, ohne dass Tickets "omg delete is defekt" vorliegen.
Laiv

Antworten:


9

Es ist in Ordnung, eine "strenge" oder "nette" Version eines Löschendpunkts zu erstellen, aber Sie müssen dem Benutzer klar mitteilen, was passiert ist.

Mit diesem Endpunkt führen wir eine Löschaktion durch. Wahrscheinlich DELETE /resource/bulk/oder ähnliches. Ich bin nicht wählerisch. Was hier zählt, ist, dass Sie, egal ob Sie sich für streng oder nett entscheiden, genau berichten müssen, was passiert ist.

Zum Beispiel hatte eine API, mit der ich gearbeitet habe, einen DELETE /v1/student/Endpunkt, der Massen-IDs akzeptierte. Wir haben die Anfrage während des Tests regelmäßig gesendet, eine 200Antwort erhalten und davon ausgegangen, dass alles in Ordnung war, um später herauszufinden, dass sich alle auf der Liste in der Datenbank noch befanden (auf inaktiv gesetzt) ​​oder aufgrund eines Fehlers nicht tatsächlich gelöscht wurden GET /v1/studentWir haben zukünftige Anrufe durcheinander gebracht, weil wir Daten zurückbekommen haben, die wir nicht erwartet hatten.

Die Lösung hierfür war ein späteres Update, bei dem der Antwort ein Text mit den nicht gelöschten IDs hinzugefügt wurde. Dies ist meines Wissens eine Art Best Practice.

Fazit: Egal, was Sie tun, stellen Sie sicher, dass Sie dem Endbenutzer eine Möglichkeit bieten, zu erfahren, was los ist und möglicherweise warum. IE, wenn wir ein striktes Format gewählt haben, könnte die Antwort sein 400 - DELETE failed on ID 1221 not found. Wenn wir eine 'schöne' Version ausgewählt haben, könnte es sein 207 - {message:"failed, some ids not deleted", failedids:{1221, 23432, 1224}}(entschuldigen Sie meine schlechte JSON-Formatierung).

Viel Glück!


6
207 Multi-Statuskönnte für diese teilweise Fehlerreaktion geeignet sein
Richard Tingle

1
NA, BITTE! Ich konnte mich nicht wirklich daran erinnern! Ich werde die Antwort damit aktualisieren, da dies tatsächlich dem Standard entspricht.
Adam Wells

2

Man sollte streng und freizügig sein.

In der Regel werden Schüttgüter in zwei Phasen unterteilt:

  • Validierung
  • Wird geladen

Während der Validierungsphase wird jeder Datensatz streng geprüft, um sicherzustellen, dass er den Anforderungen der Datenspezifikationen entspricht. In wenigen Sekunden können Sie problemlos 10 von 1000 Datensätzen einsehen. Die gültigen Datensätze werden in eine neue Datei gelegt, die geladen werden soll, die ungültigen werden markiert und entfernt und normalerweise in eine separate Datei (Datei überspringen) gestellt. Anschließend wird eine Benachrichtigung an die Datensätze gesendet, bei denen die Validierung fehlgeschlagen ist, damit sie zur Fehlerbehebung überprüft und diagnostiziert werden können.

Sobald die Daten validiert wurden, werden sie geladen. Normalerweise wird es stapelweise geladen, wenn es groß genug ist, um lang laufende Transaktionen zu vermeiden, oder wenn ein Fehler auftritt, ist die Wiederherstellung einfacher. Die Stapelgröße hängt davon ab, wie groß der Datensatz ist. Wenn man nur ein paar 1000 Datensätze hat, wäre ein Stapel in Ordnung. Hier können Sie bei Fehlern etwas tolerant sein, aber Sie möchten möglicherweise einen Schwellenwert für fehlgeschlagene Stapel festlegen, um den gesamten Vorgang zu stoppen. Wenn [N] Stapel fehlschlagen, wird möglicherweise der gesamte Vorgang gestoppt (wenn der Server ausgefallen ist oder ähnliches). Normalerweise gibt es zu diesem Zeitpunkt keine Fehler, da die Daten bereits validiert wurden. Wenn dies jedoch auf Umgebungsprobleme oder andere Probleme zurückzuführen ist, laden Sie einfach die fehlgeschlagenen Stapel neu. Dies erleichtert die Wiederherstellung ein wenig.


Ich validiere die IDs nicht anhand von DB-Werten. Ich versuche nur, sie zu löschen und zu sehen, wie das geht. Andernfalls würde es ewig dauern. Abbruch nach N Fehlern scheint ein sehr vernünftiger Vorschlag, +1
rath

2

Sollte ein einzelner Fehler eine Massenoperation fehlschlagen?

Darauf gibt es keine kanonische Antwort. Die Bedürfnisse und Konsequenzen für den Benutzer müssen untersucht und die Kompromisse bewertet werden. Das OP gab einige der erforderlichen Informationen, aber hier ist, wie ich vorgehen würde:

Frage 1 : "Was ist die Konsequenz für den Benutzer, wenn ein einzelner Löschvorgang fehlschlägt?"

Die Antwort sollte den Rest des Entwurfs / des implementierten Verhaltens bestimmen.

Wenn, wie im OP angegeben, der Benutzer lediglich die Ausnahme bemerkt und ein Trouble Ticket öffnet, aber ansonsten nicht betroffen ist (die nicht gelöschten Elemente wirken sich nicht auf nachfolgende Aufgaben aus), würde ich eine automatische Benachrichtigung zulassen für dich.

Wenn die fehlgeschlagenen Löschvorgänge behoben werden müssen, bevor der Benutzer fortfahren kann, ist streng eindeutig vorzuziehen.

Dem Benutzer die Option zu geben (z. B. im Wesentlichen ein Flag zum Ignorieren von Fehlern mit der strengen oder zulässigen Standardeinstellung), kann der benutzerfreundlichste Ansatz sein.

Frage 2 : "Gibt es Probleme mit der Datenkohärenz / -konsistenz, wenn nachfolgende Aufgaben mit nicht gelöschten Elementen ausgeführt werden, die sich noch im Datenspeicher befinden?"

Auch hier würde die Antwort das beste Design / Verhalten bestimmen. Ja -> Streng, Nein -> Zulässig, Vielleicht -> Streng oder vom Benutzer ausgewählt (insbesondere, wenn der Benutzer zur genauen Bestimmung der Konsequenzen abhängig sein kann).


0

Ich denke, das hängt davon ab, ob Sie Skalierbarkeit wollen oder nicht. Wenn Sie nicht vorhaben, viele Ausweise zu haben, sollte dies nicht allzu wichtig sein. Wenn Sie beabsichtigen, eine Million IDs zu haben, oder noch besser, nicht sicher sind, ob dies nicht der Fall ist, können Sie eine Stunde damit verbringen, IDs zu löschen, um sie aufgrund einer ungültigen ID vollständig zurückzusetzen.


-1

Ich würde sagen, ein wichtiger Punkt hier ist, was es bedeutet, dass ein Großteil der Inhalte gelöscht wird.

Sind diese IDs irgendwie logisch miteinander verbunden, oder handelt es sich nur um eine Convenience / Performance-Batch-Gruppierung dieser IDs?

Im Falle einer Art, auch locker, verbunden, würde ich mich entscheiden strict. Wenn es sich nur um einen Batch-Modus handelt (z. B. wenn der Benutzer für seine letzten Arbeitsminuten auf "Speichern" klickt und erst dann der Batch übertragen wird), würde ich mich für die permissiveVersion entscheiden.

Wie die andere Antwort besagt: Sagen Sie dem "Benutzer" auf jeden Fall genau, was passiert ist.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.