在 marklogic 9 中,如何使更新在同一个事务中可见?
In marklogic 9, how to make updates visible in the same transaction?
在 marklogic 9 中,我有一个用 xquery 编写的资源服务扩展。它是一个 'delete' 端点,因此事务模式是 'update'。我做了类似的事情:
(: 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 资源服务扩展中实现我想要的行为?
MarkLogic 完全是 ACID,因此您已经正确识别了在更新事务完成之前不会在数据库中更新文档。因此,在您 运行 第二次 cts:search 调用时,您还不会在结果中看到更新的文档,因为您的更新事务尚未完成。
我的建议通常是引导人们远离尝试在单个事务或 REST 扩展中煮沸海洋,而是在有意义的地方分解事物。在您的情况下,我建议制作一个 REST 扩展来计数或以其他方式读取数据,并制作一个 REST 扩展来执行您的节点删除更新。很可能您甚至可以使用 /v1/search 来代替编写扩展来计算文档。
如果您利用 xdmp:eval 或 xdmp:invoke 等功能,您可以在单个 REST 扩展中完成 运行 多个事务。但是,我发现以这种方式设计时,通常会使代码更难维护和调试。不必要地使用这些函数也会带来性能缺陷。
在 marklogic 9 中,我有一个用 xquery 编写的资源服务扩展。它是一个 'delete' 端点,因此事务模式是 'update'。我做了类似的事情:
(: 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 资源服务扩展中实现我想要的行为?
MarkLogic 完全是 ACID,因此您已经正确识别了在更新事务完成之前不会在数据库中更新文档。因此,在您 运行 第二次 cts:search 调用时,您还不会在结果中看到更新的文档,因为您的更新事务尚未完成。
我的建议通常是引导人们远离尝试在单个事务或 REST 扩展中煮沸海洋,而是在有意义的地方分解事物。在您的情况下,我建议制作一个 REST 扩展来计数或以其他方式读取数据,并制作一个 REST 扩展来执行您的节点删除更新。很可能您甚至可以使用 /v1/search 来代替编写扩展来计算文档。
如果您利用 xdmp:eval 或 xdmp:invoke 等功能,您可以在单个 REST 扩展中完成 运行 多个事务。但是,我发现以这种方式设计时,通常会使代码更难维护和调试。不必要地使用这些函数也会带来性能缺陷。