Hi again,
> You probably want a lock call that is blocking and returns when the lock
could be retrieved.
> Locks in jsr-170 were primarily designed to lock nodes for a longer time
and not just while
> in a transaction. Maybe a blocking variant of the getLock() method is
something we should
> consider for the next jcr version.
I just thought about something like this (Note that I've only done a few
tests on that class.) :
import javax.jcr.Credentials;
import javax.jcr.LoginException;
import javax.jcr.Node;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.observation.Event;
import javax.jcr.observation.EventIterator;
import javax.jcr.observation.EventListener;
public abstract class SerializableTemplate {
private Session session;
private Node scope;
public SerializableTemplate(Repository repository, Credentials cr,
String scopePath) throws LoginException, RepositoryException {
session = repository.login(cr);
scope = session.getRootNode().getNode(scopePath);
}
public abstract void doInTransaction(Session session);
public void execute() {
try {
if (!scope.isLocked()) {
scope.lock(true, true);
doInTransaction(session);
if (session.isLive()) {
session.logout();
}
} else {
EventListener el = new EventListener() {
public void onEvent(EventIterator events) {
try {
if (!scope.isLocked()) {
scope.lock(true, true);
doInTransaction(session);
if (session.isLive()) {
session.logout();
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
};
session.getWorkspace().getObservationManager().addEventListener(el,
Event.PROPERTY_REMOVED, scope.getPath(), true, null, null, false);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
I don't like a few things about that class, especially the constructor...
What do you think overall ?
> Again I think this always depends on the application on top of the
repository.
> Setting an isolation level as a global property does not seems to be a
good idea to me.
Well, if many applications need control of their isolation level, maybe
that feature should be implemented in one place or documented in a worked
example...
Regards,
Nicolas
Le 12:34 2005-07-08, vous avez écrit:
Hi Nicolas,
Nicolas Belisle wrote:
> no, but you may use locks to further control isolation level.
There seems to be at least two problems with that approach :
- You will get a (unpleasant) javax.jcr.lock.LockException if another
transaction tries to lock the node (or a child).
You probably want a lock call that is blocking and returns when the lock
could be retrieved. Locks in jsr-170 were primarily designed to lock nodes
for a longer time and not just while in a transaction. Maybe a blocking
variant of the getLock() method is something we should consider for the
next jcr version.
- It is not enforced even though it should be used everywhere, even for
only a read.
This depends on the application. I don't think you have to lock the
workspace when your applicaton is fine with an read-committed isolation level.
Sorry there was an error in my example. I should make more sense this way :
Example v.2 :
A : open session
A : read nodes "test" & "test2"
B : open session
B : delete nodes "test" & "test2"
B : save session //WHAT SHOULD HAPPEN ??
B : logout
A : read nodes "test" & "test2" //WHAT SHOULD HAPPEN ??
A : logout
yeah, that definitively makes more sense ;)
deleting the two nodes with Session B will be successful, unless session A
has locked the two nodes.
regarding the second attempt to read the two nodes with session A, this
depends whether A already obtained references to the nodes or not.
If A already has reference to those two nodes, calles that read the state
of those nodes will throw an InvalidItemStateException. Indicating that
the nodes do not exist anymore.
If A tries to retrieve the nodes again. E.g. by calling getNodes() on the
parent of the just deleted nodes. The returned NodeIterator will simply
not contain the nodes anymore.
It would be useful if the isolation level could configured at the
repository level. So if your application needs better isolation or
performance you would only need to change the configuration and not your code.
Again I think this always depends on the application on top of the
repository. Setting an isolation level as a global property does not seems
to be a good idea to me.
An implementation could (hypothetically) use locks in SessionImpl and use
events (when a session saves/logout) to prevent throwing exceptions. A
queue would hold pending operations. However, we would have to be careful
about long lived sessions...
I'm sorry, I cannot follow you here...
regards
marcel