With DLS, you can't do multiple changes to a version chain in a  single ML  
"Transaction" - multi statement or not.
because each update touches some of the same documents (directory, properties 
etc) you do end up with conflicting updates.

What you can do is multiple transactions mixed with multi statement 
transactions, controlled by a parent statement.
This doesn't give you the ability to use xdmp:rollback() ... each dls update 
will be committed,
but because DLS  is a version control system you can revert to previous 
versions if you need to .
Depends on what your goals are and what you really need or mean by 
"transactions" if this works for you.

Also note that what you are doing with the "latest" collections may not be 
necessary in Version 8 (available for Early Access
participants today )
In Version 8 a 'latest' collection is maintained as part of all DLS update 
transactions.



Attached is some sample code.

The issue your having passing data between statements in a multi statement 
transaction is not the same issue
as whats causing the conflicting updates ... but the solutions to both are 
solvable in several ways.

The general concept is to have a parent "query"  transaction that
eval or invoke multiple sub transactions and pass state back and forth.

Before Version 7 this would require using either separate module files or 
evaluating queries out of strings.
Both of these are non-ideal and cumbersome (or risky if you take shortcuts that 
might be open to injection attacks ).

I prefer using function items which form a 'closure' ...  It takes a helper 
function to make it simpler to read and reuse.

https://docs.marklogic.com/xdmp:invoke-function

Consider this function:

(: Run an Update statement as a separate statement but in the same transaction 
:)
declare function local:invoke-update(
  $func as function() as xs:integer
) as xs:integer
{
  xdmp:invoke-function(
   function () as xs:integer {
     let $ret := $func() ,
         $_ := xdmp:commit()
     return $ret } ,
  <options xmlns="xdmp:eval">
    <isolation>different-transaction</isolation>
    <transaction-mode>update</transaction-mode>
  </options>

  )
};


This is used in the attached queries to evaluate a function in a sub 
transaction then return its value.
That value can then be used to pass to another fuction.
Outline:

    let $n := local:invoke-update(  function { dls:document-insert-and-manage( 
... ) , xdmp:random()  } )
    return
            local:invoke-update( function() { dls: 
document-checkout-update-checkint( ... , <doc>{ $n }</doc> ) , $n  } )

The parent transaction 'sees' the results of the first insert , then passes 
that to the update via a function closure .

The 2 queries attached:
run creattest.xqy

This creates a doc and then updates it 3 times
It should output:
$ ml:query -f createtest.xqy


Versions:
Version: 1
<test xml:base="/test.xml">1</test>
Version: 2
<test xml:base="/test.xml">2</test>
Version: 3
<test xml:base="/test.xml">3</test>
Version: 4
<test xml:base="/test.xml">4</test>

Now run runms.xqy
This does a checkout/update/checkin twice , each time using the value of the 
latest document <test> element and adding 1 and checking it in.
Then it rolls back the changes using DLS by checking out the original version 
and commiting it.

This  also demonstrates transactional views in query and update mode.
Note that even at the end of the first transaction the document appears 
unchanged,
even though the sub transactions can see the changes.



It should output:

$ ml:query -f runms.xqy
First version: 4
Start of transaction: first 4 n: 5 n2: 6
Query Consistant view of doc
<test>4</test>
Next transaction Current Version
6
<test>6</test>
Reverted to Version: 4
Next transaction Current Version
6
<test xml:base="/test.xml">4</test>
Versions:
Version: 1
<test xml:base="/test.xml">1</test>
Version: 2
<test xml:base="/test.xml">2</test>
Version: 3
<test xml:base="/test.xml">3</test>
Version: 4
<test xml:base="/test.xml">4</test>
Version: 5
<test xml:base="/test.xml">5</test>
Version: 6
<test xml:base="/test.xml">6</test>
Version: 7
<test xml:base="/test.xml">4</test>


-----------------------------------------------------------------------------
David Lee
Lead Engineer
MarkLogic Corporation
d...@marklogic.com
Phone: +1 812-482-5224
Cell:  +1 812-630-7622
www.marklogic.com<http://www.marklogic.com/>

From: general-boun...@developer.marklogic.com 
[mailto:general-boun...@developer.marklogic.com] On Behalf Of Kapoor, Pragya
Sent: Tuesday, December 23, 2014 12:45 AM
To: MarkLogic Developer Discussion
Subject: Re: [MarkLogic Dev General] XDMP-CONFLICTINGUPDATES


​Hi Mike,



I read this blog, but I am unable to make 2 update statements as separate 
statements separated by semicolon as I have to check a condition based on which 
I need to update the document using dls library



Please look into the below code for details.



Thanks

Pragya

________________________________
From: 
general-boun...@developer.marklogic.com<mailto:general-boun...@developer.marklogic.com>
 
<general-boun...@developer.marklogic.com<mailto:general-boun...@developer.marklogic.com>>
 on behalf of Michael Blakeley <m...@blakeley.com<mailto:m...@blakeley.com>>
Sent: Monday, December 22, 2014 12:33 PM
To: MarkLogic Developer Discussion
Subject: Re: [MarkLogic Dev General] XDMP-CONFLICTINGUPDATES

Take a look at 
https://blakeley.com/blogofile/2013/06/21/introduction-to-multi-statement-transactions/
 — it talks about using MST with DLS.
-- Mike

On Dec 21, 2014, at 22:17, Kapoor, Pragya 
<pkapo...@innodata.com<mailto:pkapo...@innodata.com>> wrote:

Hi,



I need to run multistatement transcations in if else using dls library .

The below code is throwing error XDMP-CONFLICTINGUPDATES please let me know, 
what is the solution to this problem.



Moreover,

I tried running the below  code with declare option xdmp:transaction-mode 
"update";​ and using xdmp:commit() but still the same problem.



I need to get the documents from a directory, the first document is version 1 
of the doc, the second document in the directory is version 2 of the doc.





Code:


for $FileEntry in $sortList
  let $Filename := functx:substring-after-last(xdmp:node-uri($FileEntry),'/')
    let $count := fn:count(fn:tokenize($Filename,'_'))
    let $docUri := if($count=5) then 
fn:concat($PrefixURI,functx:substring-before-last($Filename,'_'),'.xml')  else 
fn:concat($PrefixURI,$Filename)
    let $contents := $FileEntry
let $logsXML :=
if (fn:doc-available($docUri) eq fn:false()) then
               try{

                        (: Insert the document :)
                      (dls:document-insert-and-manage(
                       $docUri,
                        fn:false(),
                       $contents,
                        "created",
                        (xdmp:permission("dls-user", "read"),
                         xdmp:permission("dls-user", "update")),
                        "historic"),
                      xdmp:document-add-collections(
                       $docUri,
                        "latest"),
                      xdmp:document-remove-collections(
                            $docUri,  "historic"),
                  (: Create metadata :)
                       local:createMetadata($docUri,$contents),
                       local:createEvents($docUri,$contents),
  local:insertPDF($transId)
                       ),

                      (
                         <uris>
                                 <uri>{$docUri}</uri>
                                 <status>Success</status>
                                 <info>Document inserted</info>
                                 <transId>{$transId}</transId>
                        </uris>
                       )


       } catch($e)
{
<uris>
<uri>{ $docUri }</uri>
<status>Failure</status>
<info>{ $e/error:format-string/text() }</info>
<transId>{ $transId }</transId>
</uris>
}
else
            try{
                (: Update the document :)
                let $update:=
( dls:document-checkout-update-checkin(
$docUri,
$contents,
"updated",
fn:true(),
(),
("historic")),
xdmp:document-add-collections(
$docUri, "latest"),
xdmp:document-remove-collections(
  $docUri,  "historic"),
(: Update metadata :)
                       local:updateMetadata($docUri,$contents),
                       local:createEvents($docUri,$contents),
                        local:insertPDF($transId)
                       )
return
   (
                         <uris>
                                 <uri>{$docUri}</uri>
                                 <status>Success</status>
                                 <info>Document inserted</info>
                                 <transId>{$transId}</transId>
                        </uris>
                       )

       } catch($e)
        {
        <uris>
            <uri>{ $docUri }</uri>
            <status>Failure</status>
            <info>{ $e/error:message/text() }</info>
            <transId>{ $transId }</transId>
        </uris>
        }


"This e-mail and any attachments transmitted with it are for the sole use of 
the intended recipient(s) and may contain confidential , proprietary or 
privileged information. If you are not the intended recipient, please contact 
the sender by reply e-mail and destroy all copies of the original message. Any 
unauthorized review, use, disclosure, dissemination, forwarding, printing or 
copying of this e-mail or any action taken in reliance on this e-mail is 
strictly prohibited and may be unlawful."
_______________________________________________
General mailing list
General@developer.marklogic.com<mailto:General@developer.marklogic.com>
http://developer.marklogic.com/mailman/listinfo/general
"This e-mail and any attachments transmitted with it are for the sole use of 
the intended recipient(s) and may contain confidential , proprietary or 
privileged information. If you are not the intended recipient, please contact 
the sender by reply e-mail and destroy all copies of the original message. Any 
unauthorized review, use, disclosure, dissemination, forwarding, printing or 
copying of this e-mail or any action taken in reliance on this e-mail is 
strictly prohibited and may be unlawful."

Attachment: createtest.xqy
Description: createtest.xqy

Attachment: runms.xqy
Description: runms.xqy

_______________________________________________
General mailing list
General@developer.marklogic.com
http://developer.marklogic.com/mailman/listinfo/general

Reply via email to