考虑以下代码:
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
执行前文档/private/test.xml不存在。我希望此代码返回插入的文档,但不返回任何内容。
我认为这是因为fn:doc()调用时文档尚未提交。 documentation表明更新语句中的更新不可见,因此我认为这是预期的行为,尽管是违反直觉的行为。
但是,这种奇怪的行为要求在将提交作为事务中的最后一个语句之前计划并在内存中进行所有更新,实质上强制所有更新函数以协调的方式工作。当然,这在设计模块化软件时产生了问题,因为它强制执行功能之间的强相互依赖性。
我找到的解决方法如下:
Forbidden 'var' keyword, use 'let' or 'const' instead (no-var-keyword)
58 | .map((response) => {
59 | // update the login status
> 60 | const tokensValid = response['isvalid'] === true;
| ^
61 | if (tokensValid) {
62 | this.loggedIn$.next(true);
63 | return true;
由于每个invoke-function()调用都在自己的事务中执行,因此可以正常工作。这对我当前的用例来说有点好,但它肯定会改变应用程序的行为,也可能会破坏许多其他情况下的一致性要求。
我的问题:这是否有更好的解决方法
谢谢你, ķ。答案 0 :(得分: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