Following Omar's message on
lock
management
[1]
I thought I would share a technique that I have tried.
It makes use of the
function
inspect:functions [2].
The code below shows two versions of an
eval-update function. After running each version the info.result view reports:
-
local:eval-update => a global write lock.
- local:eval-update2 => no locks at all!
I am pretty sure this is a bug/oversight in
inspect:functions. I suspect running it risks data integrity, so it is not a good idea.
However, I do make use of a non-updating version of this technique, as a way to do string evaluation without triggering a global read lock.
If I know that no lockable resources are referenced then it seems safe to me?
Note: inspect:functions is similar to the unimplemented standard XQuery 3.1 function
fn:load-xquery-module[3]
(:~ evaluate XQuery string, string is enriched with external variable definitions for convenience :)
declare %updating function local:eval-update($exp as xs:string,$binds as map(*)){
let $decl:= map:keys($binds)!``[declare variable $`{ . }` external;]``=>string-join("")
return xquery:eval-update($decl || $exp, $binds)
};
declare %updating function local:eval-update2($exp as xs:string,$binds as map(*)){
let $decl:= map:keys($binds)!``[let $`{ . }` :=$binds("`{ . }`") ]``=>string-join("")
let $mod:=("module namespace _='abuse'; declare %updating function
_:foo($binds){" , $decl, "return " , $exp , "};")=>string-join("")
let $p:=file:create-temp-file("APB", ".xqm")
let$_:=file:write-text($p,$mod)
return updating inspect:functions($p)($binds)
};
(: note: the bind functionality is not used in this example)
let $binds:=map{"p1":42}
let $exp:="db:replace('factbook', 'abuse.xml', '<a/>')"
return local:eval-update2($exp,$binds)