在marklogic 9中,如何使更新在同一事务中可见?

时间:2019-06-27 18:11:21

标签: marklogic marklogic-9

在marklogic 9中,我有一个用xquery编写的资源服务扩展。它是一个“删除”端点,因此事务模式为“更新”。我做了类似的事情:

(: search for objects that have /a/id = $theId :)
let $objs := cts:search(fn:doc(), cts:path-range-query('/a/id', $theId)
(: log the number of results :)
let $_ := xdmp:log(fn:count($objs))

(: for each of the objects, remove the /a/id node :)
let $_ := for ($obj in $objs) xdmp:node-delete($obj/a/id)

(: search for objects that have /a/id = $theId :)
let $objs2 := cts:search(fn:doc(), cts:path-range-query('/a/id', $theId)
(: log the number of results :)
let $_ := xdmp:log(fn:count($objs2))

我的第一个期望是记录的值将有所不同:第一个将是搜索结果的数量,第二个将始终为零,因为我从每一个中删除了“ / a / id”节点结果。但是,两个记录的值始终相同。即交易中所做的更改在扩展程序中不可见。

我在https://docs.marklogic.com/guide/app-dev/transactions#id_85012中读了updates are not visible within the updating statement,所以我试图使资源服务扩展的行为像多语句更新一样,没有运气。我也尝试在进行第二次搜索之前显式调用let $_ := xdmp:commit(),再次没有运气。

在xquery资源服务扩展中是否可以具有我想要的行为?

1 个答案:

答案 0 :(得分:2)

MarkLogic是完全ACID的,因此您可以正确地确定在更新事务完成之前不会在数据库中更新文档。因此,在您运行第二个cts:search调用时,由于更新事务尚未完成,您仍不会看到更新后的文档反映在结果中。

我的建议通常是引导人们避免尝试在单个事务或REST扩展中沸腾,而是在有意义的地方进行分解。我建议您使用一个REST扩展来计数或读取数据,并创建一个REST扩展来进行节点删除更新。您最有可能甚至可以使用/ v1 / search来代替编写用于对文档进行计数的扩展名。

如果您利用xdmp:eval或xdmp:invoke之类的功能来完成一个REST扩展中的多个事务,则可以完成此操作。但是,我发现以这种方式设计时,通常会使代码难以维护和调试。不必要地使用这些功能也会有性能缺陷。