public abstract class Locked extends Object
Locked
is a utility to synchronize modifications on a lockable
node. The modification is applied while the lock on the node is held, thus
ensuring that the modification will never fail with an InvalidItemStateException
. This utility can be used with any
JCR Repository, not just Jackrabbit.
The following example shows how this utility can be used to implement a persistent counter:
Node counter = ...; long nextValue = ((Long) new Locked() { protected Object run(Node counter) throws RepositoryException { Property seqProp = counter.getProperty("value"); long value = seqProp.getLong(); seqProp.setValue(++value); seqProp.save(); return new Long(value); } }.with(counter, false)).longValue();If you specify a
timeout
you need to check the return value
whether the run
method could be executed within the timeout
period:
Node counter = ...; Object ret = new Locked() { protected Object run(Node counter) throws RepositoryException { Property seqProp = counter.getProperty("value"); long value = seqProp.getLong(); seqProp.setValue(++value); seqProp.save(); return new Long(value); } }.with(counter, false); if (ret == Locked.TIMED_OUT) { // do whatever you think is appropriate in this case } else { // get the value long nextValue = ((Long) ret).longValue(); }
Modifier and Type | Field and Description |
---|---|
static Object |
TIMED_OUT
Object returned when timeout is reached without being able to call
run(javax.jcr.Node) while holding the lock. |
Constructor and Description |
---|
Locked() |
Modifier and Type | Method and Description |
---|---|
protected abstract Object |
run(Node node)
This method is executed while holding the lock.
|
Object |
with(Node lockable,
boolean isDeep)
Executes
run(javax.jcr.Node) while the lock on lockable is held. |
Object |
with(Node lockable,
boolean isDeep,
boolean isSessionScoped)
Executes
run(javax.jcr.Node) while the lock on lockable is held. |
Object |
with(Node lockable,
boolean isDeep,
long timeout)
Executes the method
run(javax.jcr.Node) within the scope of a lock held on
lockable . |
Object |
with(Node lockable,
boolean isDeep,
long timeout,
boolean isSessionScoped)
Executes the method
run(javax.jcr.Node) within the scope of a lock held on
lockable . |
public static final Object TIMED_OUT
run(javax.jcr.Node)
while holding the lock.public Object with(Node lockable, boolean isDeep) throws RepositoryException, InterruptedException
run(javax.jcr.Node)
while the lock on lockable
is held.
This method will block until run(javax.jcr.Node)
is executed while holding the
lock on node lockable
.lockable
- a lockable node.isDeep
- true
if lockable
will be locked
deep.run(javax.jcr.Node)
.IllegalArgumentException
- if lockable
is not
mix:lockable.RepositoryException
- if run(javax.jcr.Node)
throws an exception.InterruptedException
- if this thread is interrupted while waiting
for the lock on node lockable
.public Object with(Node lockable, boolean isDeep, boolean isSessionScoped) throws RepositoryException, InterruptedException
run(javax.jcr.Node)
while the lock on lockable
is held.
This method will block until run(javax.jcr.Node)
is executed while holding the
lock on node lockable
.lockable
- a lockable node.isDeep
- true
if lockable
will be locked
deep.isSessionScoped
- true
if the lock is session scoped.run(javax.jcr.Node)
.IllegalArgumentException
- if lockable
is not
mix:lockable.RepositoryException
- if run(javax.jcr.Node)
throws an exception.InterruptedException
- if this thread is interrupted while waiting
for the lock on node lockable
.public Object with(Node lockable, boolean isDeep, long timeout) throws UnsupportedRepositoryOperationException, RepositoryException, InterruptedException
run(javax.jcr.Node)
within the scope of a lock held on
lockable
.lockable
- the node where the lock is obtained from.isDeep
- true
if lockable
will be locked
deep.timeout
- time in milliseconds to wait at most to acquire the lock.run(javax.jcr.Node)
or TIMED_OUT
if the
lock on lockable
could not be acquired within the
specified timeout.IllegalArgumentException
- if timeout
is negative or
lockable
is not
mix:lockable.RepositoryException
- if run(javax.jcr.Node)
throws an exception.UnsupportedRepositoryOperationException
- if this repository does not support
locking.InterruptedException
- if this thread is interrupted while
waiting for the lock on node
lockable
.public Object with(Node lockable, boolean isDeep, long timeout, boolean isSessionScoped) throws UnsupportedRepositoryOperationException, RepositoryException, InterruptedException
run(javax.jcr.Node)
within the scope of a lock held on
lockable
.lockable
- the node where the lock is obtained from.isDeep
- true
if lockable
will be locked
deep.timeout
- time in milliseconds to wait at most to acquire the lock.isSessionScoped
- true
if the lock is session scoped.run(javax.jcr.Node)
or TIMED_OUT
if the
lock on lockable
could not be acquired within the
specified timeout.IllegalArgumentException
- if timeout
is negative or
lockable
is not
mix:lockable.RepositoryException
- if run(javax.jcr.Node)
throws an exception.UnsupportedRepositoryOperationException
- if this repository does not support
locking.InterruptedException
- if this thread is interrupted while
waiting for the lock on node
lockable
.protected abstract Object run(Node node) throws RepositoryException
node
- The Node
on which the lock is placed.with()
.RepositoryException
- if an error occurs.Copyright © 2004–2021 The Apache Software Foundation. All rights reserved.