tfischer    2005/02/15 23:58:49

  Modified:    src/java/org/apache/torque/util LargeSelect.java
  Log:
  Avoid ConcurrentModificationException if data is inserted into the 
LargeSelect while the first page of data is already displayed.
  Thanks to Gareth Boden and Thomas Vandahl
  In Thomas Vandahl's words:
  LargeSelect is made to retrieve a list of objects in the background
  while the Velocity template already can display the first page of
  results. This is very handy for paging through long lists of objects.
  
  The said Exception occurs if the background thread still adds objects to
  the result list while Velocity already uses an Iterator on the sublist
  of the first page. This usually happens when selects take a while.
  
  The patch simply copies the page of results instead of returning a
  sublist. This avoids the problem described above and just needs a little
  bit more memory.
  
  I have this working in a production environment for almost a year with
  no problems whatsoever.
  
  Submitted by: Gareth Boden
  
  Revision  Changes    Path
  1.16      +17 -5     
db-torque/src/java/org/apache/torque/util/LargeSelect.java
  
  Index: LargeSelect.java
  ===================================================================
  RCS file: 
/home/cvs/db-torque/src/java/org/apache/torque/util/LargeSelect.java,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- LargeSelect.java  31 Jan 2005 19:43:52 -0000      1.15
  +++ LargeSelect.java  16 Feb 2005 07:58:49 -0000      1.16
  @@ -624,7 +624,13 @@
                       + "fromIndex + Math.min(size, results.size() - 
fromIndex) ("
                       + toIndex + ")");
           }
  -        List returnResults = results.subList(fromIndex, toIndex);
  +
  +        List returnResults;
  +
  +        synchronized (results) 
  +        {
  +            returnResults = new ArrayList(results.subList(fromIndex, 
toIndex));
  +        }
   
           if (null != returnBuilderClass)
           {
  @@ -705,9 +711,12 @@
                   List tempResults
                           = BasePeer.getSelectResults(qds, size, false);
   
  -                for (int i = 0, n = tempResults.size(); i < n; i++)
  +                synchronized (results) 
                   {
  -                    results.add(tempResults.get(i));
  +                    for (int i = 0, n = tempResults.size(); i < n; i++)
  +                    {
  +                        results.add(tempResults.get(i));
  +                    }
                   }
   
                   currentlyFilledTo += tempResults.size();
  @@ -717,7 +726,10 @@
                   // on the last page but we must now get rid of it.
                   if (results.size() == memoryLimit + 1)
                   {
  -                    results.remove(currentlyFilledTo--);
  +                    synchronized (results)
  +                    {
  +                        results.remove(currentlyFilledTo--);
  +                    }
                       perhapsLastPage = false;
                   }
   
  
  
  

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

Reply via email to