【发布时间】:2018-02-16 10:18:00
【问题描述】:
我编写了一个用于生成序列号的函数。函数如下:
declare function generate-instrument-Id( $cnt as xs:int? )
as xs:int {
let $count := if( $cnt and $cnt > 0 ) then $cnt else 1
let $url := '/private/instrumentId-Sequence.xml'
(: this redirection is needed to write id in another
transaction context :)
return xdmp:invoke-function( function() {
let $id := fn:doc( $url )/instrument/@nextId
let $_ := xdmp:node-replace( $id
, attribute nextId { $id + $count } )
return $id
}
)
};
使用以下测试代码,该函数可以在 qconsole 窗口中正常工作:
let res := util:generate-instrument-Id( 1 )
return fn:error( fn:QName("test", $res ) )
即它在另一个事务上下文中执行并正确更新文档。但是,当我尝试从 REST 服务调用相同的函数时,它会返回以下错误消息:
XDMP-LOCKED: xdmp:node-replace(fn:doc("/private/instrumentId-Sequence.xml")/instrument/@nextId, attribute{fn:QName("","nextId")}{"1228"}) -- Document or Directory is locked
请注意,我清理了服务接口中的所有其他代码以隔离问题,但仍然收到相同的错误消息。
所以这是我的问题:
- 在什么情况下会发出此错误?
- 我确信没有任何其他进程对该文档(或它所在的目录)进行锁定,那么什么可能会触发这种误报?
- 由于它在 qconsole 中工作,我假设如果我复制它在执行程序时所做的事情,我也可以解决这个问题。关于 qconsole 如何执行程序的任何文档?
非常感谢
K.
PS:我在 Windows 服务器上使用 MarkLogic 9
【问题讨论】:
-
函数是否有可能被多次调用?此外,您可能想传入
<isolation>different-transaction</isolation>。这不是调用和评估的默认值。 -
@grtjn:我实际上测试了一些不同的隔离选项;它们似乎都不起作用。看起来,不同的事务是默认选项,正如在 qconsole 中正确执行该函数所证明的那样。而且,没有其他调用:确保我删除了服务代码中的所有其他调用,只留下了对该函数的调用
-
顺便问一下,您是否考虑过使用随机 ID 代替?有充分的理由更喜欢顺序 ID。详情见这里:github.com/grtjn/ml-unique#how-it-works
-
是的,我确实考虑过,但这个 id 是公开可见标识符的一部分,因此不能包含一些随机序列,但感谢链接和建议
标签: xquery marklogic marklogic-9