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]