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 2008/08/23 09:46:46 UTC
svn commit: r688275 - in
/db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/sql:
GenericStatement.java conn/GenericLanguageConnectionContext.java
Author: kahatlen
Date: Sat Aug 23 00:46:45 2008
New Revision: 688275
URL: http://svn.apache.org/viewvc?rev=688275&view=rev
Log:
DERBY-3786: Assert failure in CacheEntry.unkeepForRemove when running stress.multi
Merged fix from trunk (revision 688027).
Modified:
db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/sql/GenericStatement.java
db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java
Modified: db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/sql/GenericStatement.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/sql/GenericStatement.java?rev=688275&r1=688274&r2=688275&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/sql/GenericStatement.java (original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/sql/GenericStatement.java Sat Aug 23 00:46:45 2008
@@ -593,6 +593,16 @@
}
}
+ /**
+ * Return the {@link PreparedStatement} currently associated with this
+ * statement.
+ *
+ * @return the prepared statement that is associated with this statement
+ */
+ public PreparedStatement getPreparedStatement() {
+ return preparedStmt;
+ }
+
/*
** Identity
*/
Modified: db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java?rev=688275&r1=688274&r2=688275&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java (original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java Sat Aug 23 00:46:45 2008
@@ -29,7 +29,6 @@
import org.apache.derby.impl.sql.execute.AutoincrementCounter;
import org.apache.derby.impl.sql.GenericPreparedStatement;
import org.apache.derby.impl.sql.GenericStatement;
-import org.apache.derby.iapi.sql.Statement;
import org.apache.derby.iapi.services.property.PropertyUtil;
import org.apache.derby.iapi.services.context.ContextManager;
@@ -879,13 +878,16 @@
/**
* This method will remove a statement from the statement cache.
- * It will be called, for example, if there is an exception preparing
- * the statement.
+ * It should only be called if there is an exception preparing
+ * the statement. The caller must have set the flag
+ * {@code preparedStmt.compilingStatement} in the {@code GenericStatement}
+ * before calling this method in order to prevent race conditions when
+ * calling {@link CacheManager#remove(Cacheable)}.
*
* @param statement Statement to remove
* @exception StandardException thrown if lookup goes wrong.
*/
- public void removeStatement(Statement statement)
+ public void removeStatement(GenericStatement statement)
throws StandardException {
CacheManager statementCache =
@@ -894,9 +896,29 @@
if (statementCache == null)
return;
- Cacheable cachedItem = statementCache.findCached(statement);
- if (cachedItem != null)
- statementCache.remove(cachedItem);
+ Cacheable cachedItem = statementCache.findCached(statement);
+ // No need to do anything if the statement is already removed
+ if (cachedItem != null) {
+ CachedStatement cs = (CachedStatement) cachedItem;
+ if (statement.getPreparedStatement() != cs.getPreparedStatement()) {
+ // DERBY-3786: Someone else has removed the statement from
+ // the cache, probably because of the same error that brought
+ // us here. In addition, someone else has recreated the
+ // statement. Since the recreated statement is not the same
+ // object as the one we are working on, we don't have the
+ // proper guarding (through the synchronized flag
+ // GenericStatement.preparedStmt.compilingStatement) to ensure
+ // that we're the only ones calling CacheManager.remove() on
+ // this statement. Therefore, just release the statement here
+ // so that we don't get in the way for the other thread that
+ // is trying to compile the same query.
+ statementCache.release(cachedItem);
+ } else {
+ // The statement object that we were trying to compile is still
+ // in the cache. Since the compilation failed, remove it.
+ statementCache.remove(cachedItem);
+ }
+ }
}
/**