You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by ka...@apache.org on 2013/03/14 08:29:28 UTC

svn commit: r1456352 - in /db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access: CacheableConglomerate.java RAMAccessManager.java RAMTransaction.java

Author: kahatlen
Date: Thu Mar 14 07:29:28 2013
New Revision: 1456352

URL: http://svn.apache.org/r1456352
Log:
DERBY-5632: Logical deadlock happened when freezing/unfreezing the database

Stop using explicit synchronization on the conglomerate cache.

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/CacheableConglomerate.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/RAMAccessManager.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/RAMTransaction.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/CacheableConglomerate.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/CacheableConglomerate.java?rev=1456352&r1=1456351&r2=1456352&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/CacheableConglomerate.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/CacheableConglomerate.java Thu Mar 14 07:29:28 2013
@@ -25,6 +25,7 @@ import org.apache.derby.iapi.services.ca
 import org.apache.derby.iapi.services.sanity.SanityManager;
 import org.apache.derby.iapi.error.StandardException;
 import org.apache.derby.iapi.store.access.conglomerate.Conglomerate;
+import org.apache.derby.iapi.store.raw.ContainerKey;
 
 /**
 The CacheableConglomerate implements a single item in the cache used by
@@ -44,12 +45,14 @@ created.
 
 class CacheableConglomerate implements Cacheable
 {
+    private final RAMAccessManager accessManager;
     private Long            conglomid;
     private Conglomerate    conglom;
 
     /* Constructor */
-    CacheableConglomerate()
+    CacheableConglomerate(RAMAccessManager parent)
     {
+        this.accessManager = parent;
     }
 
 	/*
@@ -92,11 +95,15 @@ class CacheableConglomerate implements C
 	*/
 	public Cacheable setIdentity(Object key) throws StandardException
     {
-		if (SanityManager.DEBUG) {
-			SanityManager.THROWASSERT("not supported.");
-		}
+        conglomid = (Long) key;
 
-        return(null);
+        long id = conglomid.longValue();
+
+        conglom = accessManager.getFactoryFromConglomId(id).readConglomerate(
+                accessManager.getCurrentTransactionContext().getTransaction(),
+                new ContainerKey(0, id));
+
+        return this;
     }
 
 	/**

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/RAMAccessManager.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/RAMAccessManager.java?rev=1456352&r1=1456351&r2=1456352&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/RAMAccessManager.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/RAMAccessManager.java Thu Mar 14 07:29:28 2013
@@ -52,7 +52,6 @@ import org.apache.derby.iapi.store.acces
 import org.apache.derby.iapi.store.access.TransactionInfo;
 
 import org.apache.derby.iapi.store.raw.ContainerHandle;
-import org.apache.derby.iapi.store.raw.ContainerKey;
 import org.apache.derby.iapi.store.raw.LockingPolicy;
 import org.apache.derby.iapi.store.raw.RawStoreFactory;
 import org.apache.derby.iapi.store.raw.Transaction;
@@ -371,7 +370,7 @@ public abstract class RAMAccessManager
      *
 	 * @exception  StandardException  Standard exception policy.
      **/
-    private ConglomerateFactory getFactoryFromConglomId(
+    ConglomerateFactory getFactoryFromConglomId(
     long    conglom_id)
 		throws StandardException
     {
@@ -464,36 +463,12 @@ public abstract class RAMAccessManager
         Conglomerate conglom       = null;
         Long         conglomid_obj = new Long(conglomid);
 
-        synchronized (conglom_cache)
-        {
-            CacheableConglomerate cache_entry = 
-                (CacheableConglomerate) conglom_cache.findCached(conglomid_obj);
-
-            if (cache_entry != null)
-            {
-                conglom = cache_entry.getConglom();
-                conglom_cache.release(cache_entry);
-
-                // SanityManager.DEBUG_PRINT("find", "find hit : " + conglomid);
-            }
-            else
-            {
-                // SanityManager.DEBUG_PRINT("find", "find miss: " + conglomid);
+        CacheableConglomerate cache_entry =
+            (CacheableConglomerate) conglom_cache.find(conglomid_obj);
 
-                // If not in cache - ask the factory for it and insert it.
-
-                conglom = 
-                    getFactoryFromConglomId(conglomid).readConglomerate(
-                        xact_mgr, new ContainerKey(0, conglomid));
-
-                if (conglom != null)
-                {
-                    // on cache miss, put the missing conglom in the cache.
-                    cache_entry = (CacheableConglomerate) 
-                        this.conglom_cache.create(conglomid_obj, conglom);
-                    this.conglom_cache.release(cache_entry);
-                }
-            }
+        if (cache_entry != null) {
+            conglom = cache_entry.getConglom();
+            conglom_cache.release(cache_entry);
         }
 
         return(conglom);
@@ -512,49 +487,7 @@ public abstract class RAMAccessManager
     /* package */ protected void conglomCacheInvalidate()
         throws StandardException
     {
-        synchronized (conglom_cache)
-        {
-            conglom_cache.ageOut();
-        }
-
-        return;
-    }
-
-    /**
-     * Update a conglomerate directory entry.
-     * <p>
-     * Update the Conglom column of the Conglomerate Directory.  The 
-     * Conglomerate with id "conglomid" is replaced by "new_conglom".
-     * <p>
-     *
-     * @param conglomid   The conglomid of conglomerate to replace.
-     * @param new_conglom The new Conglom to update the conglom column to.
-     *
-	 * @exception  StandardException  Standard exception policy.
-     **/
-    /* package */ void conglomCacheUpdateEntry(
-    long            conglomid, 
-    Conglomerate    new_conglom) 
-        throws StandardException
-    {
-        Long         conglomid_obj = new Long(conglomid);
-
-        synchronized (conglom_cache)
-        {
-            // remove the current entry
-            CacheableConglomerate conglom_entry = (CacheableConglomerate) 
-                conglom_cache.findCached(conglomid_obj);
-
-            if (conglom_entry != null)
-                conglom_cache.remove(conglom_entry);
-
-            // insert the updated entry.
-            conglom_entry = (CacheableConglomerate) 
-                conglom_cache.create(conglomid_obj, new_conglom);
-            conglom_cache.release(conglom_entry);
-        }
-
-        return;
+        conglom_cache.ageOut();
     }
 
     /**
@@ -571,15 +504,10 @@ public abstract class RAMAccessManager
     Conglomerate    conglom)
         throws StandardException
     {
-        synchronized (conglom_cache)
-        {
-            // insert the updated entry.
-            CacheableConglomerate conglom_entry = (CacheableConglomerate) 
-                conglom_cache.create(new Long(conglomid), conglom);
-            conglom_cache.release(conglom_entry);
-        }
-
-        return;
+        // Insert the new entry.
+        CacheableConglomerate conglom_entry = (CacheableConglomerate)
+            conglom_cache.create(new Long(conglomid), conglom);
+        conglom_cache.release(conglom_entry);
     }
 
     /**
@@ -593,19 +521,45 @@ public abstract class RAMAccessManager
     /* package */ void conglomCacheRemoveEntry(long conglomid)
         throws StandardException
     {
-        synchronized (conglom_cache)
-        {
-            CacheableConglomerate conglom_entry = (CacheableConglomerate) 
-                conglom_cache.findCached(new Long(conglomid));
+        CacheableConglomerate conglom_entry = (CacheableConglomerate)
+            conglom_cache.findCached(new Long(conglomid));
 
-            if (conglom_entry != null)
-                conglom_cache.remove(conglom_entry);
+        if (conglom_entry != null) {
+            conglom_cache.remove(conglom_entry);
         }
-
-        return;
     }
 
+    /**
+     * <p>
+     * Get the current transaction context.
+     * </p>
+     *
+     * <p>
+     * If there is an internal transaction on the context stack, return the
+     * internal transaction. Otherwise, if there is a nested user transaction
+     * on the context stack, return the nested transaction. Otherwise,
+     * return the current user transaction.
+     * </p>
+     *
+     * @return a context object referencing the current transaction
+     */
+    RAMTransactionContext getCurrentTransactionContext() {
+        RAMTransactionContext rtc =
+            (RAMTransactionContext) ContextService.getContext(
+                AccessFactoryGlobals.RAMXACT_INTERNAL_CONTEXT_ID);
+
+        if (rtc == null) {
+            rtc = (RAMTransactionContext) ContextService.getContext(
+                    AccessFactoryGlobals.RAMXACT_CHILD_CONTEXT_ID);
+        }
+
+        if (rtc == null) {
+            rtc = (RAMTransactionContext) ContextService.getContext(
+                    AccessFactoryGlobals.RAMXACT_CONTEXT_ID);
+        }
 
+        return rtc;
+    }
 
     /**************************************************************************
      * Public Methods implementing AccessFactory Interface:
@@ -1280,7 +1234,7 @@ public abstract class RAMAccessManager
 	*/
 
 	public Cacheable newCacheable(CacheManager cm) {
-		return new CacheableConglomerate();
+		return new CacheableConglomerate(this);
 	}
 
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/RAMTransaction.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/RAMTransaction.java?rev=1456352&r1=1456351&r2=1456352&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/RAMTransaction.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/RAMTransaction.java Thu Mar 14 07:29:28 2013
@@ -382,17 +382,7 @@ public class RAMTransaction 
 	private Conglomerate findExistingConglomerate(long conglomId)
 		throws StandardException
 	{
-		Conglomerate conglom = null;
-
-		if (conglomId < 0)
-		{
-			if (tempCongloms != null)
-				conglom = (Conglomerate) tempCongloms.get(new Long(conglomId));
-		}
-        else
-        {
-            conglom = accessmanager.conglomCacheFind(this, conglomId);
-        }
+		Conglomerate conglom = findConglomerate(conglomId);
 
 		if (conglom == null)
         {
@@ -617,18 +607,13 @@ public class RAMTransaction 
 
 		conglom.addColumn(this, column_id, template_column, collation_id);
 
-        // remove the old entry in the Conglomerate directory, and add the
-        // new one.
-		if (is_temporary)
+        // Set an indication that ALTER TABLE has been called so that the
+        // conglomerate will be invalidated if an error happens. Only needed
+        // for non-temporary conglomerates, since they are the only ones that
+        // live in the conglomerate cache.
+        if (!is_temporary)
 		{
-			tempCongloms.put(new Long(conglomId), conglom);
-		}
-		else
-        {
             alterTableCallMade = true;
-
-            // have access manager update the conglom to this new one.
-			accessmanager.conglomCacheUpdateEntry(conglomId, conglom);
         }
 
         cc.close();
@@ -1971,12 +1956,7 @@ public class RAMTransaction 
 	public void abort()
 		throws StandardException
 	{
-	
-        if (alterTableCallMade)
-        {
-            accessmanager.conglomCacheInvalidate();
-            alterTableCallMade = false;
-        }
+        invalidateConglomerateCache();
 		this.closeControllers(true /* close all controllers */ );
 		rawtran.abort();