2017-09-07 25 views
6

Mam funkcję, którą napisałem dla generowania kolejnego numeru. Funkcja jest następujący:Otrzymuję komunikat o błędzie XDMP-LOCKED, gdy brak blokad

declare function generate-instrument-Id($cnt as xs:int?) 
as xs:int { 
    let $count := if($cnt and $cnt > 0) then $cnt else 1 
    let $url := '/private/instrumentId-Sequence.xml' 
    (: this redirection is needed to write id in another 
     transaction context :) 
    return xdmp:invoke-function(function() { 
       let $id := fn:doc($url)/instrument/@nextId 
       let $_ := xdmp:node-replace($id 
          , attribute nextId { $id + $count }) 
       return $id 
      } 
     ) 
}; 

funkcja działa poprawnie z qconsole okna przy użyciu następującego kodu testu:

let res := util:generate-instrument-Id(1) 
return fn:error(fn:QName("test", $res)) 

to znaczy wykonuje w innym kontekście transakcji i aktualizuje dokument prawidłowo. Jednak, gdy próbuję wywołać tę samą funkcję z usługi REST, zwraca się następujący komunikat o błędzie:

XDMP-LOCKED: xdmp:node-replace(fn:doc("/private/instrumentId-Sequence.xml")/instrument/@nextId, attribute{fn:QName("","nextId")}{"1228"}) -- Document or Directory is locked 

Zwróć uwagę, że czyszczone co drugi kawałek kodu z interfejsu usług wyizolować problem i nadal otrzymuje ten sam komunikat o błędzie.

Więc oto moje pytania:

  • W jakich warunkach ten błąd jest wydane?
  • Jestem pewien, że nie ma żadnych blokad na tym dokumencie (lub katalogu, w którym jest umieszczany) przez jakikolwiek inny proces, więc co może wywołać taki fałszywy alarm?
  • Ponieważ działa z qconsole, zakładam, że jeśli powtórzę to, co robi podczas wykonywania programów, mogę rozwiązać ten problem. Wszelka dokumentacja dotycząca wykonywania qconsole programów?

Thanks a lot
K.

PS: Używam MarkLogic 9 na serwerze Windows

+1

Czy jest jakaś szansa, że ​​funkcja zostanie wywołana więcej niż raz? Możesz również przekazać w ' innej transakcji'. To nie jest ustawienie domyślne dla invoke i eval. – grtjn

+0

@grtjn: Właściwie testowałem z różnymi opcjami izolacji; żaden z nich nie działa.wydaje się również, że domyślną opcją jest inna transakcja, o czym świadczy prawidłowa realizacja funkcji w qconsole. I nie ma żadnych innych połączeń: aby upewnić się, że usunąłem wszystkie inne połączenia z kodu usługi i zostawiłem tylko wywołanie tej funkcji –

+0

Przy okazji, czy zamiast tego rozważałeś użycie losowych identyfikatorów? Istnieją dobre powody, aby preferować takie sekwencyjne identyfikatory. Zobacz tutaj, aby uzyskać szczegółowe informacje: https://github.com/grtjn/ml-unique#how-it-works – grtjn

Odpowiedz

2

Po pewnym bólem, odkryłem, że powodem, dla którego otrzymał ten błąd. Wygląda na to, że rzeczywiście był zamek umieszczony w katalogu "/" i że ta blokada nie jest blokadą transakcji.

Zgodnie z documentation jest to trwała blokada, która jest pobierana przez serwer WebDAV. Podejrzewałem, że może to być związane z usługą webDAV, a ja wyłączyłem usługi WebDAV w bazie danych, zakładając, że zwolnią wszelkie blokady, które te usługi będą i byłem w stanie napisać do doc przy użyciu qconsole.

Wygląda na to, że konto administratora ma uprawnienia do ignorowania tych trwałych blokad utworzonych przez serwer webDAV, aby funkcja działała z tego kontekstu, a wyłączenie serwera WebDAV nie uwolniłoby trwałych blokad, które uzyskał.

Wszystko, co musiałem zrobić, aby rozwiązać problem, to zwolnić blokady, które kręciły się po wyłączeniu serwera webDAV.

Następnie ponownie włączyłem serwer webdav i funkcja nadal działa poprawnie, co oznaczałoby, że serwer wevDAV nabywa blokady tylko w określonych warunkach, które nie są udokumentowane.

Myślałem, powinny udostępniać te informacje, aby pomóc innym, że może widzieć ten sam problem