You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ibatis.apache.org by cb...@apache.org on 2006/01/22 03:32:10 UTC

svn commit: r371170 - in /ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine: cache/CacheModel.java mapping/statement/CachingStatement.java

Author: cbegin
Date: Sat Jan 21 18:31:59 2006
New Revision: 371170

URL: http://svn.apache.org/viewcvs?rev=371170&view=rev
Log:
Fixed IBATIS-223 Thread deadlock due to CacheModel.flush() (Sven's fix)

Modified:
    ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/cache/CacheModel.java
    ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapping/statement/CachingStatement.java

Modified: ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/cache/CacheModel.java
URL: http://svn.apache.org/viewcvs/ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/cache/CacheModel.java?rev=371170&r1=371169&r2=371170&view=diff
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/cache/CacheModel.java (original)
+++ ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/cache/CacheModel.java Sat Jan 21 18:31:59 2006
@@ -24,17 +24,14 @@
 import java.util.*;
 
 /**
- *
+ * Wrapper for Caches.
  */
 public class CacheModel implements ExecuteListener {
-
-  private static final Map lockMap = new HashMap();
   /**
    * This is used to represent null objects that are returned from the cache so
    * that they can be cached, too.
    */
   public static final Object NULL_OBJECT = new Object();
-  private final Object STATS_LOCK = new Object();
   private int requests = 0;
   private int hits = 0;
 
@@ -237,12 +234,9 @@
    * Clears the cache
    */
   public void flush() {
-    lastFlush = System.currentTimeMillis();
-    // use the controller's key
-    CacheKey key = new CacheKey();
-    key.update(controller);
-    synchronized (getLock(key)) {
+  	synchronized (this)  {
       controller.flush(this);
+      lastFlush = System.currentTimeMillis();
     }
   }
 
@@ -255,39 +249,32 @@
    * @return The cached object (or null)
    */
   public Object getObject(CacheKey key) {
+  	Object value = null;
     synchronized (this) {
       if (flushInterval != NO_FLUSH_INTERVAL
           && System.currentTimeMillis() - lastFlush > flushInterval) {
         flush();
       }
-    }
 
-    Object value = null;
-    synchronized (getLock(key)) {
       value = controller.getObject(this, key);
-    }
-
-    if (serialize && !readOnly && (value != NULL_OBJECT && value != null)) {
-      try {
-        ByteArrayInputStream bis = new ByteArrayInputStream((byte[]) value);
-        ObjectInputStream ois = new ObjectInputStream(bis);
-        value = ois.readObject();
-        ois.close();
-      } catch (Exception e) {
-        throw new NestedRuntimeException("Error caching serializable object.  Be sure you're not attempting to use " +
-            "a serialized cache for an object that may be taking advantage of lazy loading.  Cause: " + e, e);
+      if (serialize && !readOnly &&
+       	    (value != NULL_OBJECT && value != null)) {
+        try {
+          ByteArrayInputStream bis = new ByteArrayInputStream((byte[]) value);
+          ObjectInputStream ois = new ObjectInputStream(bis);
+          value = ois.readObject();
+          ois.close();
+        } catch (Exception e) {
+          throw new NestedRuntimeException("Error caching serializable object.  Be sure you're not attempting to use " +
+                                           "a serialized cache for an object that may be taking advantage of lazy loading.  Cause: " + e, e);
+        }
       }
-    }
-
-    synchronized (STATS_LOCK) {
       requests++;
       if (value != null) {
         hits++;
       }
     }
-
     return value;
-
   }
 
   /**
@@ -297,39 +284,21 @@
    * @param value The object to be cached
    */
   public void putObject(CacheKey key, Object value) {
-    if (null == value) value = NULL_OBJECT;
-    if (serialize && !readOnly && value != NULL_OBJECT) {
-      try {
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        ObjectOutputStream oos = new ObjectOutputStream(bos);
-        oos.writeObject(value);
-        oos.flush();
-        oos.close();
-        value = bos.toByteArray();
-      } catch (IOException e) {
-        throw new NestedRuntimeException("Error caching serializable object.  Cause: " + e, e);
+  	if (null == value) value = NULL_OBJECT;
+  	synchronized ( this )  {
+      if (serialize && !readOnly && value != NULL_OBJECT) {
+        try {
+          ByteArrayOutputStream bos = new ByteArrayOutputStream();
+          ObjectOutputStream oos = new ObjectOutputStream(bos);
+          oos.writeObject(value);
+          oos.flush();
+          oos.close();
+          value = bos.toByteArray();
+        } catch (IOException e) {
+          throw new NestedRuntimeException("Error caching serializable object.  Cause: " + e, e);
+        }
       }
-    }
-    synchronized (getLock(key)) {
       controller.putObject(this, key, value);
     }
   }
-
-  /**
-   * OK, honestly, i have no idea what this does.
-   * @param key
-   * @return
-   */
-  public synchronized final Object getLock(CacheKey key) {
-    int controllerId = System.identityHashCode(controller);
-    int keyHash = key.hashCode();
-    Integer lockKey = new Integer(29 * controllerId + keyHash);
-    Object lock = lockMap.get(lockKey);
-    if (lock == null) {
-      lock = lockKey; //might as well use the same object
-      lockMap.put(lockKey, lock);
-    }
-    return lock;
-  }
-
 }

Modified: ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapping/statement/CachingStatement.java
URL: http://svn.apache.org/viewcvs/ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapping/statement/CachingStatement.java?rev=371170&r1=371169&r2=371170&view=diff
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapping/statement/CachingStatement.java (original)
+++ ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapping/statement/CachingStatement.java Sat Jan 21 18:31:59 2006
@@ -76,10 +76,8 @@
     	//	This was cached, but null
     	object = null;
     }else if (object == null) {
-      synchronized (cacheModel.getLock(cacheKey)) {
-        object = statement.executeQueryForObject(request, trans, parameterObject, resultObject);
-        cacheModel.putObject(cacheKey, object);
-      }
+       object = statement.executeQueryForObject(request, trans, parameterObject, resultObject);
+       cacheModel.putObject(cacheKey, object);
     }
     return object;
   }
@@ -96,10 +94,8 @@
       // The cached object was null
       list = null;
     }else if (listAsObject == null) {
-      synchronized (cacheModel.getLock(cacheKey)) {
-        list = statement.executeQueryForList(request, trans, parameterObject, skipResults, maxResults);
-        cacheModel.putObject(cacheKey, list);
-      }
+      list = statement.executeQueryForList(request, trans, parameterObject, skipResults, maxResults);
+      cacheModel.putObject(cacheKey, list);
     }else{
       list = (List) listAsObject;
     }