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;
}