Loading TOC...
Application Developer's Guide (PDF)

Application Developer's Guide — Chapter 8

Document and Directory Locks

This chapter describes locks on documents and directories, and includes the following sections:

Overview of Locks

Each document and directory can have a lock. A lock is stored as a locks document in a MarkLogic Server database. The locks document is separate from the document or directory to which it is associated. Locks have the following characteristics:

Write Locks

Locks are write locks; they restrict updates from all users who do not have the locks. When a user has an exclusive lock, no other users can get a lock and no other users can update or delete the document. Attempts to update or delete documents that have locks raise an error. Other users can still read documents that have locks, however.

Persistent

Locks are persistent in the database. They are not tied to a transaction. You can set locks to last a specified time period or to last indefinitely. Because they are persistent, you can use locks to ensure that a document is not modified during a multi-transaction operation.

Searchable

Because locks are persistent XML documents, they are therefore searchable XML documents, and you can write queries to give information about locks in the database. For an example, see Example: Finding the URI of Documents With Locks.

Exclusive or Shared

You can set locks as exclusive, which means only the user who set the lock can update the associated database object (document, directory, or collection). You can also set locks as shared, which means other users can obtain a shared lock on the database object; once a user has a shared lock on an object, the user can update it.

Hierarchical

When you are locking a directory, you can specify the depth in a directory hierarchy you want to lock. Specifying "0" means only the specified URI is locked, and specifying "infinity" means the URI (for example, the directory) and all of its children are locked.

Locks and WebDAV

WebDAV clients use locks to lock documents and directories before updating them. Locking ensures that no other clients will change the document while it is being saved. It is up to the implementation of a WebDAV client as to how it sets locks. Some clients set the locks to expire after a time period and some set them to last until they explicitly unlock the document.

Other Uses for Locks

Any application can use locks as part of its update strategy. For example, you can have a policy that a developer sets a lock for 30 seconds before performing an update to a document or directory. Locks are very flexible, so you can set up a policy that makes sense for your environment, or you can choose not to use them at all.

If you set a lock on every document and directory in the database, that can have the effect of not allowing any data to change in the database (except by the user who owns the lock). Combining a application development practice of locking and using security permissions effectively can provide a robust multi-user development environment.

Lock APIs

There are basically two kinds of APIs for locks: APIs to show locks and APIs to set/remove locks. For detailed syntax for these APIs, see the online XQuery Built-In and Module Function Reference.

The APIs to show locks are:

The xdmp:document-locks function with no arguments returns a sequence of locks, one for each document lock. The xdmp:document-locks function with a sequence of URIs as an argument returns the locks for the specified document(s). The xdmp:directory-locks function returns locks for all of the documents in the specified directory, and the xdmp:collection-locks function returns all of the locks for documents in the specified collection.

You can set and remove locks on directories and documents with the following functions:

  • xdmp:lock-acquire
  • xdmp:lock-release

The basic procedure to set a lock on a document or a directory is to submit a query using the xdmp:lock-acquire function, specifying the URI, the scope of lock requested (exclusive or shared), the hierarchy affected by the lock (just the URI or the URI and all of its children), the owner of the lock, the duration of the lock

The owner of the lock is not the same as the sec:user-id of the lock. The owner can be specified as an option to xdmp:lock-acquire. If owner is not explicitly specified, then the owner defaults to the name of the user who issued the lock command. For an example, see Example: Finding the User to Whom a Lock Belongs.

Example: Finding the URI of Documents With Locks

If you call the XQuery built-in xdmp:node-uri function on a locks document, it returns the URI of the document that is locked. The following query returns a document listing the URIs of all documents in the database that have locks.

<root>
{
for $locks in xdmp:document-locks()
return <document-URI>{xdmp:node-uri($locks)}</document-URI>
}
</root>

For example, if the only document in the database with a lock has a URI /document/myDocument.xml, then the above query would return the following.

<root>
  <document-URI>/documents/myDocument.xml</document-URI>
</root>

Example: Setting a Lock on a Document

The following example uses the xdmp:lock-acquire function to set a two minute (120 second) lock on a document with the specified URI:

xdmp:lock-acquire("/documents/myDocument.xml",
                   "exclusive",
                   "0",
                   "Raymond is editing this document",
                   xs:unsignedLong(120))

You can view the resulting lock document with the xdmp:document-locks function as follows:

xdmp:document-locks("/documents/myDocument.xml")

=>

<lock:lock xmlns:lock="http://marklogic.com/xdmp/lock">
  <lock:lock-type>write</lock:lock-type>
  <lock:lock-scope>exclusive</lock:lock-scope>
  <lock:active-locks>
    <lock:active-lock>
      <lock:depth>0</lock:depth>
      <lock:owner>Raymond is editing this document</lock:owner>
      <lock:timeout>120</lock:timeout>
      <lock:lock-token>
       http://marklogic.com/xdmp/locks/4d0244560cc3726c
      </lock:lock-token>
      <lock:timestamp>1121722103</lock:timestamp>
      <sec:user-id xmlns:sec="http://marklogic.com/xdmp/security">
         8216129598321388485
      </sec:user-id>
    </lock:active-lock>
  </lock:active-locks>
</lock:lock>

Example: Releasing a Lock on a Document

The following example uses the xdmp:lock-release function to explicitly release a lock on a document:

xdmp:lock-release("/documents/myDocument.xml")

If you acquire a lock with no timeout period, be sure to release the lock when you are done with it. If you do not release the lock, no other users can update any documents or directories locked by the xdmp:lock-acquire action.

Example: Finding the User to Whom a Lock Belongs

Because locks are documents, you can write a query that finds the user to whom a lock belongs. For example, the following query searches through the sec:user-id elements of the lock documents and returns a set of URI names and user IDs of the user who owns each lock:

for $x in xdmp:document-locks()//sec:user-id
return  <lock>
           <URI>{xdmp:node-uri($x)}</URI>
           <user-id>{data($x)}</user-id>
        </lock>

A sample result is as follows (this result assumes there is only a single lock in the database):

<lock> 
  <URI>/documents/myDocument.xml</URI> 
  <user-id>15025067637711025979</user-id> 
</lock>
« Previous chapter
Next chapter »