cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From johnth...@apache.org
Subject svn commit: r1423537 - in /cayenne/main/trunk: docs/doc/src/main/resources/ framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/
Date Tue, 18 Dec 2012 17:19:55 GMT
Author: johnthuss
Date: Tue Dec 18 17:19:55 2012
New Revision: 1423537

URL: http://svn.apache.org/viewvc?rev=1423537&view=rev
Log:
CAY-1782 Fix deadlock when performing many concurrent inserts

Removed:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/LongPkRange.java
Modified:
    cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/JdbcPkGenerator.java

Modified: cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt?rev=1423537&r1=1423536&r2=1423537&view=diff
==============================================================================
--- cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt (original)
+++ cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt Tue Dec 18 17:19:55 2012
@@ -61,3 +61,4 @@ CAY-1755 FaultFailureException resolving
 CAY-1757 ROP: Faulting entity relationship resets uncommitted modifications made to its reverse
relationship 
 CAY-1774 EhCacheQueryCache.get(QueryMetadata, QueryCacheEntryFactory) returns null if EhCache
instance for group is not present
 CAY-1780 cdbimport do not create xml file in resource folder
+CAY-1782 Deadlock when performing many concurrent inserts

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/JdbcPkGenerator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/JdbcPkGenerator.java?rev=1423537&r1=1423536&r2=1423537&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/JdbcPkGenerator.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/JdbcPkGenerator.java
Tue Dec 18 17:19:55 2012
@@ -26,10 +26,14 @@ import java.sql.SQLException;
 import java.sql.Statement;
 import java.sql.Types;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
+import java.util.Comparator;
+import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.DataRow;
@@ -52,7 +56,7 @@ public class JdbcPkGenerator implements 
     public static final int DEFAULT_PK_CACHE_SIZE = 20;
 
     protected JdbcAdapter adapter;
-    protected Map<String, LongPkRange> pkCache = new HashMap<String, LongPkRange>();
+    protected ConcurrentHashMap<String, SortedSet<Long>> pkCache = new ConcurrentHashMap<String,
SortedSet<Long>>();
     protected int pkCacheSize = DEFAULT_PK_CACHE_SIZE;
 
     public JdbcPkGenerator(JdbcAdapter adapter) {
@@ -253,21 +257,32 @@ public class JdbcPkGenerator implements 
             value = longPkFromDatabase(node, entity);
         }
         else {
-            synchronized (pkCache) {
-                LongPkRange r = pkCache.get(entity.getName());
+            SortedSet<Long> pks = pkCache.get(entity.getName());
 
-                if (r == null) {
-                    // created exhausted LongPkRange
-                    r = new LongPkRange(1l, 0l);
-                    pkCache.put(entity.getName(), r);
+            if (pks == null) {
+                // created exhausted LongPkRange
+                pks = new TreeSet<Long>();
+                SortedSet<Long> previousPks = pkCache.putIfAbsent(entity.getName(),
pks);
+                if (previousPks != null) {
+                	pks = previousPks;
                 }
+            }
 
-                if (r.isExhausted()) {
-                    long val = longPkFromDatabase(node, entity);
-                    r.reset(val, val + cacheSize - 1);
-                }
+            if (pks.isEmpty()) {
+            	long val = longPkFromDatabase(node, entity);
+            	SortedSet<Long> nextPks = mkSortedSetFromRange(val, val + cacheSize -
1);
+            	while (!pkCache.replace(entity.getName(), pks, nextPks)) {
+            		pks = pkCache.get(entity.getName()); // the cache for this entity has changed,
so re-fetch it then update
+            		SortedSet<Long> previousPlusNext = new TreeSet<Long>(pks);
+            		previousPlusNext.addAll(nextPks);
+            		nextPks = previousPlusNext;
+            	}
+            	pks = nextPks;
+            }
 
-                value = r.getNextPrimaryKey();
+            synchronized (pkCache) {
+                value = pks.first();
+                pks.remove(value);
             }
         }
 
@@ -280,7 +295,15 @@ public class JdbcPkGenerator implements 
         }
     }
 
-    /**
+    private SortedSet<Long> mkSortedSetFromRange(long min, long max) {
+    	SortedSet<Long> result = new TreeSet<Long>();
+    	for (long i = min; i <= max; i++) {
+    		result.add(i);
+    	}
+    	return result;
+    }
+
+	/**
      * Performs primary key generation ignoring cache. Generates a range of primary keys
      * as specified by "pkCacheSize" bean property.
      * <p>



Mime
View raw message