我在这里有一个测试用例:
let $s :=
'xquery version "1.0-ml";
for $doc in xdmp:directory("/test/")
return
xdmp:node-insert-child(doc(xdmp:node-uri($doc))/a,
<b>bbb</b>)
return
(xdmp:eval($s, (), <options xmlns="xdmp:eval">
<isolation>different-transaction</isolation>
<prevent-deadlocks>true</prevent-deadlocks>
</options>), xdmp:directory("/test/"))
我的主要目标是在“/ test /”中为每个文档添加一个新元素,并在同一个事务中返回结果。使用xdmp:eval()
和“不同事务”选项,我认为评估代码将在一个单独的事务中执行,其更新可用于后续调用...所以第二个和最后一个xdmp:directory("/test/")
应该使用<b>
元素返回所有更新的文档,但它返回未更新的文档。
这里有xdmp:eval
有什么警告以及我想在一次交易中实现的目标吗?
答案 0 :(得分:3)
Marklogic 8 在这种情况下,我的想法是我在从主脚本调用的函数中进行更新。我使用的设置不仅提交文档,还将新提交公开给初始代码。由于MarkLogic如何处理代码中的时间戳,只是因为某些东西可能被提交并不意味着它可用于代码。为什么?因为提交的时间戳是在代码开始运行之后(或类似的东西)。这种方法解决了这个问题。此外,我选择了MarkLogic 8示例,因为原始问题并未将其范围扩展到先前版本。所以我选择了当前版本的MarkLogic的解决方案。
xquery version "1.0-ml";
(: load docs
for $foo in (1 to 5)
let $uri := "/test/child/foo" || xs:string($foo) || ".xml"
return xdmp:document-insert($uri, <foo><bar></bar></foo>)
:)
let $update := xdmp:invoke-function(function(){
(for $uri in cts:uri-match("/test/child/foo*")
return xdmp:node-insert-child(doc($uri)/foo/bar, <baz>bbb</baz>)
,xdmp:commit()
)
},
<options xmlns="xdmp:eval">
<transaction-mode>update-auto-commit</transaction-mode>
<isolation>different-transaction</isolation>
</options>
)
return xdmp:directory("/test/child/")