Shalini
Shalini

Reputation: 348

Incremental Counter giving XDMP-CONFLICTINGUPDATES in Marklogic

I want to automatically increase the URI of the document to be inserted based on a condition but for single document it is working and for multiple documents I am getting XDMP CONFLICTINGUPDATES

Code :

if ($results) then 
    local:replace($results, $i )
else if($i) then
    (
        let $counter := 10000000
        let $uri := concat("/test-", ($counter+1),".xml")
        return (xdmp:document-insert($uri, $i , (), "collection"), "Document inserted")
    )
else "No document"

Upvotes: 0

Views: 86

Answers (1)

Rob S.
Rob S.

Reputation: 3609

It's very difficult to tell what your code is doing based on this limited sampling.

However, this is likely your problem:

let $counter := 10000000
let $uri := concat("/test-", ($counter+1),".xml")
return (xdmp:document-insert($uri, $i , (), "collection"), "Document inserted")

If you are inserting a document to the same URI multiple times within a single transaction then I would expect the error you are seeing.

There are multiple solutions to this, however it's tough to know which one is best without knowing what you are trying to do. The most equivalent solution would be to do something like this :

let $counter := map:map()
let $_ := map:put($counter, "counter", 1)

...

if ($results) then 
local:replace($results, $i )
else if($i) then
(
    let $counterValue := map:get($counter, "counter")
    let $_ := map:put($counter, "counter", $counterValue+1)
    let $uri := concat("/test-", ($counterValue),".xml")
    return (xdmp:document-insert($uri, $i , (), "collection"), "Document inserted")
)
else "No document"

This way, you're preserving the last value of counter and correctly incrementing it each time you insert a document. Note, you may not need a map to hold the value depending on how your code is written but I strongly suspect you do.

In response to your comments.. For a very simple demonstration of this technique, compare the results of :

let $counter := 1

for $i in (1 to 10)
let $counter := $counter + 1
return $counter

To:

let $counter := map:map()
let $_ := map:put($counter, "counter", 1)

for $i in (1 to 10)
  let $counterValue := map:get($counter, "counter")
  let $_ := map:put($counter, "counter", $counterValue+1)
  return $counterValue

Upvotes: 4

Related Questions