Hi Nicolas,

I can see where you are heading for ;)

I think the constructor take the node that acts as the lock scope. It should provide all that is needed:

public SerializableTemplate(Node scope) {
        session = scope.getSession();
        this.scope = scope;
}

you may then also ommit the session parameter in doInTransaction. And just as a minor improvement the method should be allowed to throw a RepositoryException.

After checking whether a node is locked it is not guaranteed that you can then lock the node. A similar concurrency problem can arise when isLocked() returns true, between that call and the listener registration the node might get unlocked. so, you don't get an event for that and keep waiting.

regards
 marcel

Nicolas Belisle wrote:
I just thought about something like this (Note that I've only done a few tests on that class.) :

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

Reply via email to