jackrabbit-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Nicolas Belisle <Nicolas.Beli...@bibl.ulaval.ca>
Subject Re: Problems with concurrent sessions
Date Thu, 21 Jul 2005 18:46:13 GMT
Hi Marcel,

If all three tryLock() fail, the event is certainly active. The event is 
then waiting for an ACTIVE lock to be released (the last tryLock() confirms 
that fact). The event is not cancelled/removed until the lock is obtained. 
Then doInTransaction() is called.

The only way I see to stop the transaction from executing is to stop the 
server...

Am I missing something ?

Regards,

Nicolas


Le 05:54 2005-07-19, vous avez écrit:
>Hi Nicolas,
>
>Looks better now, but there are still cases where the doTransaction() 
>method will not be called, though very unlikely: when all three tryLock() 
>attempts fail. not very likely but theoretically possible...
>
>regards
>  marcel
>
>Nicolas Belisle wrote:
>>Hi,
>>Thanks again for your comments.
>>Here's the second version of my template class. It should resolves the 
>>concurrency issues you mentionned :
>>package app;
>>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.lock.LockException;
>>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;
>>     private boolean done = false;
>>     private EventListener el;
>>     public SerializableTemplate(Repository repository, Credentials cr, 
>> String scopePath) throws LoginException, RepositoryException {
>>         session = repository.login(cr);
>>         scope = session.getRootNode().getNode(scopePath);
>>         //scope = session.getNodeByUUID(scope.getUUID());
>>     }
>>     public abstract void doInTransaction(Session session) throws 
>> RepositoryException;
>>     public void execute() throws RepositoryException {
>>         if (tryLock()) {
>>             return;
>>         }
>>         this.el = new EventListener() {
>>             public void onEvent(EventIterator events) {
>>                 try {
>>                     tryLock();
>>                 } catch (RepositoryException e) {
>>                     throw new RuntimeException(e);
>>                 }
>>             }
>>         };
>>
>>session.getWorkspace().getObservationManager().addEventListener(el, 
>>Event.PROPERTY_REMOVED, scope.getPath(), true, null, null, false);
>>         //Try again, in case the lock is removed before observer could 
>> be put in place
>>         tryLock();
>>     }
>>     private synchronized boolean tryLock() throws RepositoryException {
>>         try {
>>             if (done) {
>>                 return false;
>>             }
>>             if (!scope.isLocked()) {
>>                 scope.lock(true, true);
>>                 try {
>>                     if (el != null) {
>>
>>session.getWorkspace().getObservationManager().removeEventListener(el);
>>                     }
>>                     doInTransaction(session);
>>                 } finally {
>>                     done = true;
>>                     if (session.isLive()) {
>>                         session.logout();
>>                     }
>>                 }
>>                 return true;
>>             }
>>         } catch (LockException e) {
>>             e.printStackTrace();
>>         }
>>         return false;
>>     }
>>}
>>Here's how to use it :
>>SerializableTemplate sTemplate = new SerializableTemplate(repository, new 
>>SimpleCredentials("user", "password".toCharArray()), "node/path") {
>>         //@Override
>>         public void doInTransaction(Session session) throws 
>> RepositoryException {
>>                 //Do your favorite transaction...
>>         };
>>sTemplate.execute();
>>
>>For the constructor you suggested, I actually came up with a similiar 
>>design at first, but found a problem with it : since the template class 
>>might use an EventListener the class should be responsible for closing 
>>the session (the EventListener can wait a while...). Else, the event 
>>could be removed by the user before being invoked. That's the reason for 
>>my ugly constructor.
>>I welcome your comments again...
>>Regards,
>>Nicolas


Mime
View raw message