===Commands===
Database locking works All commands come with all commandsa detector for local locks. Global locking is applief applied if the glob syntax is used:
* {{Code|DROP DB new*}}: drop Drop all databases starting with "the prefix string {{Code|new"}}.
===XQuery===
Deciding which databases will be accessed Since BaseX 10, the [[BaseX 10#Compilation|lock detection has been fundamentally improved]], by a complex XQuery expression is a non-trivial tasksplitting compilation into multiple steps. Database detection works for the following types of queries:
* {{Code|//item}}, read-locking of the Local locks can be applied if it is possible after compile time to associate all database opened by a client* {{Code|doc('factbook')}}, read-locking of "factbook"* {{Code|collection('db/path/to/docs')}}, read-locking of "db"* {{Code|delete nodes db:get('test')//*[string-length(local-name(.)) > 5]}}, write-locking of "test"* {{Code|fnoperations with static databases names:sum(1 to 100)}} (no lock)
A global {| class="wikitable"|- valign="top"! Query! Description|- valign="top"| <code>//item</code>| Read lock will be assigned if of the currently opened database|- valign="top"| <code>doc('factbook')</code>| Read lock of the {{Code|factbook}} database|- valign="top"| <code>collection('documents/path/to/docs')</code>| Read lock of the {{Code|documents}} database|- valign="top"| <code>delete nodes db:get('test')//*[@type = 'misc']</code>| Write lock of the name {{Code|test}} database|- valign="top"| <code>declare variables $db external;<br/>db:get($db)</code>| Read lock of the database externally bound to {{Code|$db}}.|- valign="top"| <code>for $db in ('db1', 'db2')<br/>return db:get($db)</code>| Read lock of {{Code|db1}} and {{Code|db2}}, as the query is not a static string[[XQuery Optimizations#Loop Unrolling|unrolled at compile time]].|- valign="top"| <code>let $db := 'test'<br/>return insert nodes <test/> into db:get($db)</code>| Read lock of {{Code|test}}, as the [[XQuery Optimizations#Variable_Inlining|variable is inlined]] at compile time.|- valign="top"| <code>sum(1 to 100)</code>| No lock required|- valign="top"| <code>declare variable $SIMULATE := true();<br/>if($SIMULATE) then <doc/> else db:get('doc')</code>| No lock required, as the query is simplified to {{Code|<doc/>}} at compile time.|}
* {{Code|for $db in ('db1', 'db2') return dbA global lock will be assigned if the static detection fails:get($db)}}* {{Code|doc(doc('test')/reference/text())}}* <code>let $db := 'test' return insert nodes <test/> into db:get($db)</code>
The functions {{Code|fnclass="wikitable"|- valign="top"! Query! Description|- valign="top"| <code>db:get(doc}} and {{Code('test')/reference/text())</code>|fn:collection}} can also The name of the database to be opened will only be used to address that are not stored in a databaseknown at evaluation time. However, this may lead |- valign="top"| <code>(1 to unwanted locks100) ! db:get(concat('db', and you have two options to reduce the number of locks: No database lookups will take place if .))</code>| The {{Option|WITHDBUNROLLLIMIT}} option is disabled, or if can be increased to generate 100 {{Function|FetchCode|fetchdb:docget}} is used instead of {{Codefunction calls and corresponding locks.|fn:doc}}.
The functions {{Code|fn:doc}} and {{Code|fn:collection}} can be used for both accessing databases resources and fetching resources at the specified URI (see [[Databases#Access Resources|Access Resources]] for more details). There are two ways to reduce the number of locks: # Turn off the {{Option|WITHDB}} option to prevent the functions from accessing databases; or# use {{Function|Fetch|fetch:doc}} for fetching resources from URIs, and use {{Function|Database|db:get}} for accessing databases. You can consult the query info output (which you find in via the [[GUI#Visualizations|Info View]] of the GUI or which you can turn on by setting , via {{OptionCode|QUERYINFO-V}} to on [[Command-Line]] or via turning on the {{CodeOption|trueQUERYINFO}}option) to find out which databases have been are locked by a query, and if local locks or a global lock is applied.
=XQuery Locks=
By default, access to external resources (files on hard disk, HTTP requests, ...…) is not controlled by the transaction monitor of BaseX. Custom locks can be assigned via annotations, pragmas or options:
* A lock string may consist of a single key or multiple keys separated with commas.
In the following module, lock annotations are used to prevent concurrent write operations on the same file:
<syntaxhighlight pre lang="'xquery"'>
module namespace config = 'config';
file:write-text('config.txt', $data)
};
</syntaxhighlightpre>
Some explanations:
* If a query calls the a reading <code>configbasex:readlock</code> function, a read lock will be acquired for the user-defined {{Code|CONFIG}} lock string before query evaluation.* If an updating <code>configbasex:writelock</code> is called by a query, a write lock will be applied.* If another query calls a <code>configbasex:writelock</code>function, it will be queued until the first query is evaluated.
==Pragmas==
Locks can also be declared via pragmas:
<syntaxhighlight pre lang="'xquery"'>
update:output((# basex:lock CONFIG #) {
file:write('config.xml', <config/>)
})
</syntaxhighlightpre>
The write locks is enforced via the {{Code|Update|update:output}}.
Locks for the functions of a module can also be assigned via option declarations:
<syntaxhighlight pre lang="'xquery"'>
declare option basex:lock 'CONFIG';
update:output(file:write('config.xml', <config/>))
</syntaxhighlightpre>
Once again, a write lock is enforced.
=Changelog=
;Version 10.0
* Updated: Lock detection was improved by splitting compilation into multiple steps.
;Version 9.4