Changes

Jump to navigation Jump to search
1,634 bytes added ,  18:36, 1 December 2023
m
Text replacement - "<syntaxhighlight lang="xquery">" to "<pre lang='xquery'>"
* Locks ''cannot be synchronized'' across BaseX instances that run in different JVMs. If concurrent write operations are to be performed, we generally recommend working with the client/server or the HTTP architecture .
* An ''unexpected abort'' of the server during a transaction, caused by a hardware failure or power cut, may lead to an inconsistent database state if a transaction was active at shutdown time. So it It is advisable to use the [[Commands#{{Command|CREATE BACKUP|BACKUP]] }} command to regularly backup back up your database. If the worst case occurs, you can try the [[Commands#INSPECT{{Command|INSPECT]] }} command to check if your database has obvious inconsistencies, and use [[Commands#RESTORE{{Command|RESTORE]] }} to restore the last backed up version of the database.
==XQuery Update==
* By default, read transactions are favored, and transactions that access no databases can be evaluated even if the transactions limit has been reached. This behavior can be changed via the {{Option|FAIRLOCK}} option.
==Limitations== ===Commands=== All commands come with a detector for local locks. Global locking is applied if the glob syntax is used: * {{Code|DROP DB new*}}: Drop all databases starting with the prefix string {{Code|new}}. ===XQuery=== Since BaseX 10, the [[BaseX 10#Compilation|lock detection has been fundamentally improved]], by splitting compilation into multiple steps. Local locks can be applied if it is possible after compile time to associate all database operations with static databases names: {| class="wikitable"|- valign="top"! Query! Description|- valign="top"| <code>//item</code>| Read lock 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 {{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 [[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 LocksOptimizations#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.|} A global lock will be assigned if the static detection fails: {| class="wikitable"|- valign="top"! Query! Description|- valign="top"| <code>db:get(doc('test')/reference/text())</code>| The name of the database to be opened will only be known at evaluation time.|- valign="top"| <code>(1 to 100) ! db:get(concat('db', .))</code>| The {{Option|UNROLLLIMIT}} can be increased to generate 100 {{Code|db:get}} function calls and corresponding locks.|} 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 (via the [[GUI#Visualizations|Info View]] of the GUI, via {{Code|-V}} on [[Command-Line]] or via turning on the {{Option|QUERYINFO}} option) to find out which databases are locked by a query, and if local locks or a global lock is applied.
By default, access to external resources (files on hard disk, HTTP requests, ...) is not controlled by the transaction monitor of BaseX. You can use custom =XQuery locks to do so:Locks=
===Option DeclarationsBy default, Pragmasaccess to external resources (files on hard disk, Function Annotations===HTTP requests, …) is not controlled by the transaction monitor of BaseX. Custom locks can be assigned via annotations, pragmas or options:
{{Mark|Introduced * A lock string may consist of a single key or multiple keys separated with Version 9commas.1}}: * Internal locks via pragmas and function annotationsXQuery locks can co-exist. No conflicts arise, even if a lock string equals the name of a database that is locked by the transaction manager.* The lock is transformed into a write lock by making the corresponding expression updating.
* You can declare custom read and write locks via options, pragmas or function annotations.* The value of the lock may contain one or multiple lock keys (separated with commas).* Similar to the internal database locks, write locks block all other operations while read locks allow parallel access.* The internal locks and XQuery locks can co-exist (there will be no conflicts, even if your lock string equals the name of a database that will be locked by the transaction manager).==Annotations==
In the following module, lock annotations are used to prevent concurrent write operations on the same file:
<pre classlang="brush:'xquery"'>
module namespace config = 'config';
declare %basex:read-lock('CONFIG') function config:read() as xs:string {
file:read-text('config.txt')
};
declare %updating %basex:write-lock('CONFIG') function config:write($dataas xs:string) {
file:write-text('config.txt', $data)
};
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 on this lock string will be set for this queryapplied.* If a another query calls a <code>configbasex:writelock</code>function, it will be queued until there is no running query left that has {{Code|CONFIG}} locked.* If the writing first query will be is evaluated, all other queries that will set a {{Code|CONFIG}} lock (reading or writing) will have to wait==Pragmas==
Local locks Locks can also be declared via pragmas:
<pre classlang="brush:'xquery"'>update:output((# basex:write-lock CONFIG #) {
file:write('config.xml', <config/>)
})
</pre>
Locks for The write locks is enforced via the functions of a module can be assigned via option declarations{{Code|Update|update:output}}.
<pre class="brush:xquery">declare option basex:write-lock 'CONFIG';file:write('config.xml', <config/>)</pre>=Options==
Before {{Version|9.1}}, locks were declared in Locks for the {{Code|query}} namespace.functions of a module can also be assigned via option declarations:
<pre lang===Java Modules==='xquery'>declare option basex:lock 'CONFIG';
Locks can also be acquired on [[Java Bindings#Locking|Java functions]] which are imported and invoked from an XQuery expression. It is advisable to explicitly lock Java code whenever it performs sensitive read and update:output(file:write operations('config.xml', <config/>)) ==Limitations== ===Commands===</pre>
Database locking works with all commands unless the glob syntax Once again, a write lock is used, such as in the following command call:enforced.
* {{Code|DROP DB new*}}: drop all databases starting with "new"==Java Modules==
===XQuery=== Deciding which databases will Locks can also be accessed by a complex XQuery expression is a non-trivial task. Database detection works for the following types of queries: * {{Code|//item}}, read-locking of the database opened by a client* {{Code|doc('factbook')}}, read-locking of "factbook"* {{Code|collection('db/path/to/docs')}}, read-locking of "db"* {{Code|fn:sum(1 to 100)}}, locking nothing at all* {{Code|delete nodes doc('test')//*[string-length(local-name(.)) > 5]}}, write-locking of "test" All databases will be locked by queries of the following kind: * {{Code|for $db in ('db1', 'db2') return doc($db)}}* {{Code|doc(doc('test')/reference/text())}}* <code>let $db := 'test' return insert nodes <test/> into doc($db)</code> You can consult the query info output (which you find in the acquired on [[GUIJava Bindings#VisualizationsLocking|Info ViewJava functions]] of the GUI or which you can turn on by setting <are imported and invoked from an XQuery expression. It is advisable to explicitly lock Java code>[[Options#QUERYINFO|QUERYINFO]]</code> to {{Code|true}}) to find out which databases have been locked by a querywhenever it performs sensitive read and write operations.
=File-System Locks=
=Changelog=
 
;Version 10.0
* Updated: Lock detection was improved by splitting compilation into multiple steps.
 
;Version 9.4
* Updated: Single lock option for reads and writes.
;Version 9.1
Bureaucrats, editor, reviewer, Administrators
13,554

edits

Navigation menu