A repository maysupportlocking, which enables a user to temporarily preventother users from changing a node or subgraph of nodes.
Whether animplementation supports locking can be determined by querying therepository descriptor table with
.
A return value ofindicates support (see §24.2Repository Descriptors).
A lock is placed on anode by calling(see §17.11.1LockManager.lock). The node on which a lock isplaced is called the holding node of that lock. Only nodeswith mixin node type(inherited as part of their primary node type or explicitlyassigned) may hold locks. The definition ofis:
A lock can bespecified as eithershallow ordeep. A shallow lockapplies only to its holding node and its properties. A deep lockapplies to its holding node and all its descendants. Consequently,there is a distinction between a lockbeing held by a nodeand a lockapplying to a node. A lock always applies to itsholding node. However, if it is a deep lock, it also applies to allnodes in the holding node's subgraph. When a lock applies to a node,that node is said to belocked.
Since a deep lockapplies to all nodes in the lock-holding node's subgraph, this mayinclude bothnodes and non-nodes. The deep lock applies to both categories of node equally anditdoes not add anyorproperties to any of the deep-lockednodes. However, if any such nodes exist and they already have theseproperties, this means that they are already locked, and hence theattempt to deep lock above them will fail.
Additionally, assuminga deep lock exists above anode, any attempt to lock this lower levelnode will also fail, because it is already locked from above.
Initially, the session through which alock is placed is theowner of that lock. This means thesession has the power to alter the locked node and to remove thelock. In the case of open-scoped locks (as opposed tosession-scoped, see §17.7Session-Scoped and Open-Scoped Locks)control of the lock may be given to another session during thelifetime of that lock. In some implementations giving control of alock to another session will remove control from the previoussession, in others, more than one session may simultaneously own thesame open-scoped lock.
Repositories may supportclient-specified lock owner information. If this is the case, theproperty will be set to the value supplied upon lock creation, andwill not change during the lifetime of the lock. Otherwise, when alock is created, theproperty is set to the user ID bound to the locking(that is, the string returned by)or another implementation-dependent string identifying the user.
In implementations that do not supportclient-specified lock owner information, when an open-scoped lock ismoved to a new owner, or assigned an additional one (if supported),theproperty may be automatically altered to reflect the change.
Strictly speaking it is the session,not the user, that owns a particular lock at a particular time. Theproperty is used for informational purposes, so that a clientapplication can, for example, display this information to otherusers. For this reason the user is sometimes informally referred toas the lock owner.
In implementations that record theuser ID in,that user will not automatically have the ability to alter thelocked node if accessing it through another session. Transfer (or,if supported, addition) of ownership must be done explicitly fromone session to another and is not governed by the user ID associatedwith a session.
Whenis performed on anode, the properties defined in that node type are automaticallycreated and set as follows:
is set to the supplied owner info, the user ID associated with thesession that set the lock (this is the value returned by)or another implementation-dependent string identifying the user.
is set to reflect whether the lock is deep or not.
Whenis performed on a lockednode, through a session that owns the lock these two properties areremoved.
Additionally, the content repositorymay give permission to some sessions to remove locks for which theyare not the owner. Typically such “lock-superuser” capability isintended to facilitate administrational clean-up of orphanedopen-scoped locks.
An attempt to callor.for a node that is notwill throw a,as will an attempt to lock an already locked node or unlock analready unlocked node.
The methodreturns aobject. If the lock is open-scoped the lock will contain a locktoken. A lock token is a string that uniquely identifies aparticular lock and acts as a key granting lock ownership to anysession that hold the token.
In order to use thelock token as a key, it must be added to the session, thuspermitting that session to alter the nodes to which the lock appliesor to remove the lock. When a lock token is attached to a,the session becomes an owner of the lock.
The methodautomatically adds the lock token for a newly placed open-scopedlock to the current session.
The client can alsocontrol which lock tokens are attached to the session through themethods,and.
When a lock is placedon a node, it can be specified to be either a session-scoped lock oran open-scoped lock. A session-scoped lock automatically expireswhen the session through which the lock owner placed the lockexpires. An open-scoped lock does not expire until it is explicitlyunlocked, it times out or an implementation-specific limitationintervenes.
In the case ofopen-scoped locks, the lock token must be attached to the currentsession in order to alter any nodes locked by that token's lock.
In the case ofsession-scoped locks, the user need not explicitly do anything sincethe lock is automatically associated with the session and expireswith it in any case.
With open–scopedlocks the token is automatically attached to the session. However,the user must additionally ensure that a reference to the lock tokenis preserved separately so that it can later be attached to anothersession since, presumably, an open-scoped lock is being used toavoid co-expiration with the initial session. It is for handlingthese cases of attaching an existing lock token from a previoussession to a new session that the methods,andare provided (see §17.11LockManager Object).
To determine anexisting lock’s scoping, the methodis provided.
If ais session-scoped, the methodcan be used to determine whether the current session is the lockowner.
An implementationmaysupport simultaneous ownership of open-scoped locks across sessions.
If a lock applies to anode (i.e., the node either holds the lock or is a descendant of anode holding a deep lock), then to all sessions except thelock-owning session, the same restrictions apply with respect to thenode as would apply if the node were protected (see §3.7.2.2Protected).
Removing a node isconsidered an alteration ofits parent. This means that anode within the scope of a lock may be removed by a session that isnot an owner of that lock, assuming no other restriction preventsthe removal. Similarly, a locked node and its subgraph may be movedby a non-lock-owning session if no restriction prevents thealteration of the source and destination parent nodes.
Locked nodes can always be read and copied by any session withsufficient access privileges.
When an action isprevented due to a lock, ais thrown either immediately or on thesubsequent.Implementations may differ on which of these behaviors is used toenforce locking.
There is at most onelock on any node at one time.
Implementations maysupport client-supplied timeout information, but are not required todo so. Additionally, an implementation may remove (unlock) any lockat any time due to implementation-specific criteria.
When a new node isadded below a deep lock by that lock's owning sessionwill report trueeven before the node is persisted21.However, since the node is not visible to others,its locked status has no effect until it is persisted.
begin
do A
do B
commit
In this example theandhave no effect. This series of operations is equivalent to:
begin
do A
do B
commit
The reason for this isthat changes to a workspace are only made visible to othersupon commit of the transaction, and this includes changes in thelocked status of a node. As a result, if a lock is enabled and thendisabled within the same transaction, its effect never makes it tothe persistent workspace and therefore it does nothing.
In order to use locksproperly (that is, to prevent the “lost update problem”),locking and unlocking must be done in separate transactions. Forexample:
begin
commit
begin
do A
do B
commit
This series ofoperations would ensure that the actionsA andB areprotected by the lock.
The methods forlocking, unlocking and querying the locking status of a node arefound in the,acquired through
.
places a lock on thenode at.If successful, the node is said tohold the lock.
Ifisthen the lockapplies to the specified node and all itsdescendant nodes; if,the lock applies only to the specified node. On a successful lock,theproperty of the locked node is set to this value.
Ifisthen this lock will expire upon the expiration of the currentsession (either through an automatic or explicit);if,this lock does not expire until it is explicitly unlocked, it timesout, or it is automatically unlocked due to animplementation-specific limitation.
Theparameter specifies the number of seconds until the lock times out(if it is not refreshed in the meantime, see §10.11.1Refresh).An implementation may use this information as a hint or ignore italtogether. Clients can discover the actual timeout by inspectingthe returnedobject.
Theparameter can be used to pass a string holding owner informationrelevant to the client. An implementation may either use or ignorethis parameter. If it uses the parameter it must set theproperty of the locked node to this value and return this value on.If it ignores this parameter theproperty (and the value returned by)is set to either the value returned byof the owning session or an implementation-specific stringidentifying the owner.
The method returns aobject representing the new lock.
If the lock isopen-scoped the returned lock will include a lock token. The locktoken is also automatically added to the set of lock tokens held bythe current.
The addition or changeof the propertiesandare persisted immediately; there is no need to call.
It is possible to locka node even if it is checked-in (see §15.2.2Read-Only onCheck-In).
returns theobject that applies to the node at absPath. This may be either alock on the node itself or a deep lock on a node above that node.
If the current sessionholds the lock token for this lock and the lock is open-scoped, thenthe returnedobject contains that lock token (accessible through).If thisdoes not hold the applicable lock token and the lock is open-scoped,the returnedobjectmay return the lock token. Otherwise, the returnedobject will not contain the lock token and itsmethod will return(see §17.12.4Getting a Lock Token).
Removes the lock, andthe propertiesand,from the node at.These changes are persisted automatically; there is no need to call.As well, the corresponding lock token is removed from the set oflock tokens held by the current session.
If this node does notcurrently hold a lock or holds a lock for which thisis not the owner, then ais thrown.
The system may givepermission to a non-owning session to unlock a lock. Typically such“lock-superuser” capability is intended to facilitateadministrational clean-up of orphaned open-scoped locks.
It is possible tounlock a node even if it is checked-in (see §15.2.2Read-Only onCheck-In).
returnsif the node atholds a lock; otherwise returns.Tohold a lock means that the node has actually had a lockplaced on it specifically, as opposed to having a lockapplyto it due to a deep lock held by a node above.
returnsif the node at absPath is locked either as a result of a lock heldby the specified node or by a deep lock on a node above that node;otherwise returns.
Alternatively, themethod
can be used directlyon the node in question.
adds the specifiedlock token to the current session. Holding a lock token makes thissession the owner of the lock specified by that particular locktoken. If the implementation does not support simultaneous lockownership this method will transfer ownership of the lockcorresponding to the specifiedto the current session, otherwise the current session will become anadditional owner of that lock. In either case, if the implementationdoes not support client-specified lock owner information, thismethod may cause a change in theproperty (and the value returned by)of the lock corresponding to the specified(see §17.5Lock Token).
returns an arraycontaining all lock tokens currently held by the current session.Note that any such tokens will represent open-scoped locks, sincesession–scoped locks do not have tokens.
Removes the specifiedfrom the current session, causing the session to no longer be anowner of the lock associated with the.If the implementation does not support client-specified lock ownerinformation, this method may cause a change in theproperty (and the value returned by)of the lock corresponding to the specified(see §17.5Lock Token).
Theobject represents a lock on a particular node. It is acquired eitheron lock creation throughor after lock creation through.
returns the value oftheproperty. This is either the client-supplied lock owner information,the user ID bound to the session that holds the lock or animplementation-specific string identifying the user (see §4.4.1User).
The lock owner'sidentity is only provided for informational purposes. It does notgovern who can perform an unlock or make changes to the lockednodes; that depends entirely upon the session that holds the locktoken.
returnsif this is a deep lock;otherwise.
returns the lockholding node. Note that(whereis a locked node) will only returnifis the lock holder. Ifis in the subgraph of the lock holder,,then this call will return.
may return the locktoken for this lock. If this lock is open-scoped and the currentsession holds the lock token for this lock, then this method willreturn that lock token. If the lock is open-scoped and the currentsession does not hold the lock token, itmay return the locktoken. Otherwise this method will return.
returnsif thisobject represents a lock that is currently in effect. If this lockhas been unlocked either explicitly or due to animplementation-specific limitation (like a timeout) then it returns.Note that this method is intended for those cases where one isholding aJava object and wants to find out whether the lock (therepository-level entity that is attached to the lockable node) thatthis object originally represented still exists. For example, atimeout or explicitwill remove a lock from a node but theJava object corresponding to that lock may still exist, and in thatcase itsmethod will return.
Returnsif this is a session-scoped lock and the scope is bound to thecurrent session. Returnsotherwise.
Returnsif the current session is the owner of this lock, either because itis session-scoped and bound to this session or open-scoped and thissession currently holds the token for this lock. Returnsotherwise.
If this lock'stime-to-live is governed by a timer, the number of remaining secondsuntil time out is returned. If this lock's time-to-live is notgoverned by a timer, then this method returns.
If this lock'stime-to-live is governed by a timer, this method resets that timer.If this lock's time-to-live is not governed by a timer, then thismethod has no effect.
Whena method fails due to the presence or absence of a lock on aparticular node ais thrown.
extends,adding the method
,
whichreturns the absolute path of the node that caused the error, orif the implementation chooses not to, or cannot, return a path.