-2

考虑这段代码:

xquery version "1.0-ml";

let $_ := xdmp:document-insert("/private/test.xml", <t13 /> )
let $doc := fn:doc( "/private/test.xml" )     
return $doc

文件 /private/test.xml 在执行前不存在。我希望这段代码返回插入的文档,但什么也不返回。

我认为这是因为在进行 fn:doc() 调用时文档尚未提交。该文档表明更新语句中的更新不可见,因此我认为这是预期的行为,尽管这是违反直觉的行为。

但是,这种奇怪的行为需要在将提交作为事务中的最后一条语句之前在内存中计划和进行所有更新,本质上强制所有更新功能以协调的方式工作。当然,这在设计模块化软件时会产生问题,因为它在执行功能之间强制执行强相互依赖性。

我找到的解决方法如下:

let $_ := xdmp:invoke-function( function() {  xdmp:document-insert("/private/test.xml", <t13 /> ) } )
let $doc := xdmp:invoke-function( function() { fn:doc( "/private/test.xml" ) }  )
return $doc

由于每个 invoke-function() 调用都在其自己的事务中执行,因此这是可行的。这对于我当前的用例来说还可以,但它肯定会改变应用程序的行为,并且可能会破坏许多其他情况的一致性要求。

我的问题:有没有更好的解决方法

谢谢你,K。

4

1 回答 1

2

这是非常预期的行为,而不是奇怪的行为。XQuery 的本质是一切都必须以任何顺序执行。一切都是事务性的,所以正如您所发现的,您不能在同一个事务中创建和读取文档。

在提供的代码示例中执行您正在执行的操作的最简单方法是:

xdmp:document-insert("/private/test.xml", <t13 /> )
;
fn:doc( "/private/test.xml" )

插入分号可确保两个命令在单独的事务中运行。

使用插入文档的主模块xdmp:invoke-function()可以更好地使用您的示例。xdmp:invoke()您可以传递包括 uri、内容、权限和集合在内的参数,或者在主模块中具有相应的逻辑。

Application Developer's Guide 中有很好的处理事务的文档:https ://docs.marklogic.com/guide/app-dev/transactions

于 2017-09-28T04:27:17.607 回答