wburrows    2004/12/07 17:33:52

  Modified:    src/webdav/server/org/apache/slide/webdav/method
                        AbstractWebdavMethod.java
  Log:
  Defect 32250: fixes to solve db deadlocks when client transaction used.
  
  Revision  Changes    Path
  1.66      +63 -20    
jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/AbstractWebdavMethod.java
  
  Index: AbstractWebdavMethod.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/AbstractWebdavMethod.java,v
  retrieving revision 1.65
  retrieving revision 1.66
  diff -u -r1.65 -r1.66
  --- AbstractWebdavMethod.java 7 Dec 2004 17:47:47 -0000       1.65
  +++ AbstractWebdavMethod.java 8 Dec 2004 01:33:52 -0000       1.66
  @@ -405,23 +405,31 @@
                   globalLockObtained = true;
               }
   
  -            try {
  -                // retrive to check it exists, otherwise it can't have locks
  -                structure.retrieve(slideToken, requestUri);
  -                // clear expired lock-tokens
  -                UnlockListenerImpl listener = new 
UnlockListenerImpl(slideToken, token, config, req, resp);
  -                lock.clearExpiredLocks(slideToken, requestUri, listener);
  -                
  -                if (listener.getUnlockCount() > 0) {
  -                    // If we have have cleared any lock or any lock-null 
resource in   
  -                    // the previous step we commit this changes, otherwise 
they will  
  -                    // be lost if executeRequest() exits with an exception 
(e.g. 
  -                    // because of Not Found 404)
  -                    token.commit();
  -                    token.begin();
  +            /*
  +             * Check for object existence and cleanup locks but only if this 
is
  +             * not a request to finalize an external transaction. Otherwise 
we are
  +             * making calls to the store that require a transaction to be in 
process 
  +             * while we're trying to commit or abort the current transaction.
  +             */            
  +            if (!isEndofTransactionRequest()) {
  +                try {
  +                    // retrive to check it exists, otherwise it can't have 
locks
  +                    structure.retrieve(slideToken, requestUri);
  +                    // clear expired lock-tokens
  +                    UnlockListenerImpl listener = new 
UnlockListenerImpl(slideToken, token, config, req, resp);
  +                    lock.clearExpiredLocks(slideToken, requestUri, listener);
  +                    
  +                    if (listener.getUnlockCount() > 0) {
  +                        // If we have have cleared any lock or any lock-null 
resource in   
  +                        // the previous step we commit this changes, 
otherwise they will  
  +                        // be lost if executeRequest() exits with an 
exception (e.g. 
  +                        // because of Not Found 404)
  +                        token.commit();
  +                        token.begin();
  +                    }
  +                } catch (ObjectNotFoundException e) {
  +                    // ignore, it can't have locks
                   }
  -            } catch (ObjectNotFoundException e) {
  -                // ignore, it can't have locks
               }
               
               boolean done = false;
  @@ -504,8 +512,16 @@
       protected void executeRedirect() throws AccessDeniedException, 
LinkedObjectNotFoundException,
               ObjectLockedException, RevisionDescriptorNotFoundException, 
ServiceAccessException,
               VetoException, WebdavException, IOException {
  +        
           boolean responseIsRedirected = false;
  -        if (!requestHeaders.getApplyToRedirectRef(false)) {
  +        
  +        /* 
  +         * Check whether to apply to redirect ref but only if this is not an
  +         * external transaction request to commit or abort the current 
transaction. 
  +         * Otherwise db deadlock can occur.
  +         */            
  +        if (!requestHeaders.getApplyToRedirectRef(false)
  +                && !isEndofTransactionRequest()) {
               try {
                   NodeRevisionDescriptors revisionDescriptors
                           = content.retrieve(slideToken, requestUri);
  @@ -551,6 +567,7 @@
                   // TODO not sure, but this makes nonOwnerUsesLocktoken 
testcase passing 
               }
           }
  +        
           if (!responseIsRedirected) {
               executeRequest();
           }
  @@ -558,6 +575,32 @@
       
       // --------------------------------------------------------- Public 
Methods
   
  +
  +    /**
  +     * Returns a boolean indicating whether this request is an
  +     * external transaction request to commit or abort the
  +     * current transaction. These requests must be given a
  +     * short path to UnlockMethod.execute() that avoids db
  +     * interaction -- even reads. 
  +     *
  +     * @return true if the current request is an external transaction commit 
or abort request.
  +     */
  +    public boolean isEndofTransactionRequest()
  +    {
  +        /*
  +         * if this is an UnlockMethod and has a transaction
  +         * command set in the request then this request is
  +         * trying to commit or abort an external transaction.
  +         */
  +        if (this instanceof UnlockMethod)
  +        {
  +            UnlockMethod meth = (UnlockMethod)this;
  +            if (meth.getCommand() != UnlockMethod.NO_TRANSACTION)
  +                return true;
  +        }
  +        
  +        return false;
  +    }
   
       /**
        * Returns the configuration of the WebdavServlet.
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to