Warum kann ich bestimmte Ausnahmen in einer MarkLogic-Anfrage nicht abfangen?

8

Ich habe Code, der die Einstellung "ungültige Werte" für einen Elementbereichsindex ausübt . In diesem Fall habe ich einen dateTime Elementbereichsindex für das Element onDate in meiner Datenbank konfiguriert (was sowohl für XML-Elemente als auch für JSON-Eigenschaften gilt). Ich habe diesen Index so eingestellt, dass er ungültige Werte zurückweist. Diese Einstellung bedeutet, wenn ich versuche, den Wert eines onDate -Elements zu setzen, und nicht in dateTime umwandelbar oder null (literal null in JSON oder xsi:nil="true" in XML), schlägt meine Aktualisierung fehl. (Das entgegengesetzte Verhalten besteht darin, ungültige Werte vollständig zu ignorieren.)

Ich habe den folgenden Code in serverseitigem JavaScript in MarkLogic 8.0-4 ausprobiert:

%Vor%

Ich hätte erwartet, dass meine Anfrage erfolgreich ist und mit 1 === errors.length endet, weil nur die zweite Einfügung fehlgeschlagen wäre, weil 'asdf' nicht als dateTime castbar ist und nicht null ist. Stattdessen bekomme ich einen XDMP-RANGEINDEX Fehler und meine Transaktion schlägt fehl. Warum funktioniert mein try / catch hier nicht?

    
Justin Makeig 01.03.2016, 19:19
quelle

1 Antwort

13

Das Problem besteht darin, wie MarkLogic Update-Transaktionen verarbeitet. Statt die Daten tatsächlich mit jedem xdmp.docuentInsert(…) -Aufruf zu ändern, reiht MarkLogic alle Aktualisierungen in die Warteschlange ein und wendet sie am Ende der Anforderung atomar an. (Dies ist auch der Grund, warum Datenbankaktualisierungen innerhalb derselben Transaktion nicht angezeigt werden können.) Daher wird der Fehler erst nach der Ausführung der Schleife ausgelöst, und die Datenbank versucht, die eingereihten Transaktionen zu übernehmen. Dieses Verhalten ist in XQuery (etwas vereinfacht) das gleiche:

%Vor%

Um die Fehler synchron zu erfassen, müssen Sie jedes Update in eine eigene Transaktion einfügen. Im Allgemeinen ist dieser Ansatz wesentlich langsamer und ressourcenintensiver als die Standard-Transaktionsverarbeitung von MarkLogic. Es ist jedoch illustrativ, um zu demonstrieren, was unter den Abdeckungen passiert und kann für bestimmte Anwendungsfälle wie diese nützlich sein.

Im folgenden Beispiel verwende ich xdmp.invokeFunction() , um eine Funktion in einer separaten Transaktion vom übergeordneten Element "aufzurufen" anfordern. (Erstklassige Funktionen für den Gewinn!) Dadurch können die Updates vollständig angewendet (oder mit einem Fehler zurückgesetzt) ​​und das aufrufende Modul die Updates (oder Fehler) sehen. Ich habe die Low-level xdmp.invokeFunction() in meiner eigenen applyAs() -Funktion eingeschlossen, um einige Feinheiten zu liefern, wie zB die Übergabe von Funktionsargumenten an die Curry-Funktion.

%Vor%     
Justin Makeig 01.03.2016, 19:19
quelle

Tags und Links