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."
createtest.xqy
Description: createtest.xqy
runms.xqy
Description: runms.xqy
_______________________________________________ General mailing list General@developer.marklogic.com http://developer.marklogic.com/mailman/listinfo/general