You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2006/06/16 16:37:39 UTC

svn commit: r414839 - /incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/IncrementalFaultList.java

Author: aadamchik
Date: Fri Jun 16 07:37:38 2006
New Revision: 414839

URL: http://svn.apache.org/viewvc?rev=414839&view=rev
Log:
IncrementalFaultList deadlock fix.

When connection pool size is less than the number of concurrent requests, doing commit and filling in IncrementalFaultList in parallel eventually causes a deadlock. 
IncrementalFaultList is holding an open connection and trying to get a lock on DataRowStore, while a committing thread that locked DataRowStore can's get a connection, 
cause the pool is empty. 


(I can't log in to Jira due to Apache network problems; I will enter the bug once this is resolved)

Modified:
    incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/IncrementalFaultList.java

Modified: incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/IncrementalFaultList.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/IncrementalFaultList.java?rev=414839&r1=414838&r2=414839&view=diff
==============================================================================
--- incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/IncrementalFaultList.java (original)
+++ incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/IncrementalFaultList.java Fri Jun 16 07:37:38 2006
@@ -221,6 +221,7 @@
             rowWidth = 0;
 
             try {
+                int lastResolved = 0;
                 long t1 = System.currentTimeMillis();
                 ResultIterator it = dataContext.performIteratedQuery(query);
                 try {
@@ -230,20 +231,12 @@
                     // resolve first page if we can
                     if (resolvesFirstPage()) {
                         // read first page completely, the rest as ObjectIds
-                        List firstPage = (fetchesDataRows) ? elements : new ArrayList(
-                                pageSize);
                         for (int i = 0; i < pageSize && it.hasNextRow(); i++) {
-                            firstPage.add(it.nextDataRow());
+                            elements.add(it.nextDataRow());
+                            lastResolved++;
                         }
 
-                        // convert rows to objects
-                        if (!fetchesDataRows) {
-                            elements.addAll(dataContext.objectsFromDataRows(
-                                    rootEntity,
-                                    firstPage,
-                                    info.isRefreshingObjects(),
-                                    info.isResolvingInherited()));
-                        }
+                        // defer DataRows -> Objects conversion till we are completely done.
                     }
 
                     // continue reading ids
@@ -255,10 +248,23 @@
                     QueryLogger.logSelectCount(elements.size(), System
                             .currentTimeMillis()
                             - t1);
-
                 }
                 finally {
                     it.close();
+                }
+                
+                // fill in the first page AFTER the iterator was closed, otherwise we may
+                // cause an (unobvious) deadlock due to connection pool exhaustion 
+                if (!fetchesDataRows && lastResolved > 0) {
+                    List objects = dataContext.objectsFromDataRows(
+                            rootEntity,
+                            elements.subList(0, lastResolved),
+                            info.isRefreshingObjects(),
+                            info.isResolvingInherited());
+                    
+                    for(int i = 0; i < lastResolved; i++) {
+                        elements.set(i, objects.get(i));
+                    }
                 }
             }
             catch (CayenneException e) {