Return-Path: Delivered-To: apmail-db-derby-commits-archive@www.apache.org Received: (qmail 57006 invoked from network); 25 Aug 2008 15:28:57 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 25 Aug 2008 15:28:57 -0000 Received: (qmail 17159 invoked by uid 500); 25 Aug 2008 15:28:55 -0000 Delivered-To: apmail-db-derby-commits-archive@db.apache.org Received: (qmail 17128 invoked by uid 500); 25 Aug 2008 15:28:55 -0000 Mailing-List: contact derby-commits-help@db.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: "Derby Development" List-Id: Delivered-To: mailing list derby-commits@db.apache.org Received: (qmail 17119 invoked by uid 99); 25 Aug 2008 15:28:55 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 25 Aug 2008 08:28:55 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 25 Aug 2008 15:28:06 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 83893238896C; Mon, 25 Aug 2008 08:28:36 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r688756 - in /db/derby/code/trunk/java/engine/org/apache/derby: iapi/services/locks/ iapi/sql/dictionary/ iapi/store/access/ iapi/store/raw/ impl/store/access/ impl/store/raw/xact/ Date: Mon, 25 Aug 2008 15:28:36 -0000 To: derby-commits@db.apache.org From: kahatlen@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080825152836.83893238896C@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: kahatlen Date: Mon Aug 25 08:28:35 2008 New Revision: 688756 URL: http://svn.apache.org/viewvc?rev=688756&view=rev Log: DERBY-3693: Deadlocks accessing DB metadata Added more detailed comments and cross references in the javadoc. Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/locks/LockOwner.java db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/SPSDescriptor.java db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/access/TransactionController.java db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/Transaction.java db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/RAMTransaction.java db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/Xact.java Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/locks/LockOwner.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/locks/LockOwner.java?rev=688756&r1=688755&r2=688756&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/locks/LockOwner.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/locks/LockOwner.java Mon Aug 25 08:28:35 2008 @@ -29,6 +29,24 @@ * cannot be granted at once, even if {@code C_LockFactory.TIMED_WAIT} * was specified in the lock request. * + *

+ * + * Normally, this method should return {@code false}, but in some very + * special cases it could be appropriate to return {@code true}. One + * example is when a stored prepared statement (SPS) is compiled and stored + * in a system table. In order to prevent exclusive locks in the system + * table from being held until the transaction that triggered the + * compilation is finished, the SPS will be compiled in a nested + * transaction that is committed and releases all locks upon completion. + * There is however a risk that the transaction that triggered the + * compilation is holding locks that the nested transaction needs, in + * which case the nested transaction will time out. The timeout will be + * detected by the calling code, and the operation will be retried in the + * parent transaction. To avoid long waits in the cases where the nested + * transaction runs into a lock conflict with its parent, the nested + * transaction's {@code LockOwner} instance could return {@code true} and + * thereby making it possible to detect lock conflicts instantly. + * * @return {@code true} if timed waits should time out immediately, * {@code false} otherwise */ Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/SPSDescriptor.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/SPSDescriptor.java?rev=688756&r1=688755&r2=688756&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/SPSDescriptor.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/SPSDescriptor.java Mon Aug 25 08:28:35 2008 @@ -694,7 +694,11 @@ nestedTC = lcc.getTransactionCompile().startNestedUserTransaction(false); // DERBY-3693: The nested transaction may run into a lock // conflict with its parent transaction, in which case we - // don't want to wait for a timeout. + // don't want to wait for a timeout. If a lock timeout is + // detected while we're executing the nested transaction, + // we ignore the error and retry in the user transaction. + // When retrying in the user transaction, we'll wait for + // locks if necessary. nestedTC.setNoLockWait(true); } catch (StandardException se) Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/access/TransactionController.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/access/TransactionController.java?rev=688756&r1=688755&r2=688756&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/access/TransactionController.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/access/TransactionController.java Mon Aug 25 08:28:35 2008 @@ -1483,10 +1483,17 @@ /** * Tell this transaction whether it should time out immediately if a lock - * cannot be granted without waiting. + * cannot be granted without waiting. This mechanism can for instance be + * used if an operation is first attempted in a nested transaction to + * reduce the lifetime of locks held in the system tables (like when + * a stored prepared statement is compiled and stored). In such a case, + * the caller must catch timeout exceptions and retry the operation in the + * main transaction if a lock timeout occurs. * * @param noWait if {@code true} never wait for a lock in this transaction, * but time out immediately + * @see org.apache.derby.iapi.services.locks.LockOwner#noWait() + * @see org.apache.derby.iapi.store.raw.Transaction#setNoLockWait(boolean) */ public void setNoLockWait(boolean noWait); Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/Transaction.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/Transaction.java?rev=688756&r1=688755&r2=688756&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/Transaction.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/Transaction.java Mon Aug 25 08:28:35 2008 @@ -61,10 +61,16 @@ /** * Tell this transaction whether it should time out immediately if a lock - * cannot be granted without waiting. + * cannot be granted without waiting. This could be used in a nested + * transaction to prevent long waits if there is a lock conflict between + * the nested transaction and its parent. If it is used this way, the + * calling code should catch timeout exceptions from the nested transaction + * and retry the operation (without disabling waiting) in the parent + * transaction. * * @param noWait if {@code true} never wait for a lock in this transaction, * but time out immediately + * @see org.apache.derby.iapi.services.locks.LockOwner#noWait() */ void setNoLockWait(boolean noWait); 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=688756&r1=688755&r2=688756&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 Mon Aug 25 08:28:35 2008 @@ -2436,17 +2436,13 @@ } /** - * Tell this transaction whether it should skip waiting for locks and - * instead time out immediately. + * {@inheritDoc} * *

* * For now, this only works if the transaction has its own compatibility * space. If it has inherited the compatibility space from its parent, * the request will be ignored (or cause a failure in debug builds). - * - * @param noWait if {@code true} never wait for a lock, but time out - * immediately */ public void setNoLockWait(boolean noWait) { rawtran.setNoLockWait(noWait); Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/Xact.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/Xact.java?rev=688756&r1=688755&r2=688756&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/Xact.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/Xact.java Mon Aug 25 08:28:35 2008 @@ -584,8 +584,7 @@ } /** - * Set whether lock requests should time out immediately if they can't be - * granted without waiting. + * {@inheritDoc} * *

* @@ -593,9 +592,6 @@ * space used in the request. If this transaction has inherited the * compatibility space from its parent, the call to this method has no * effect (except in debug builds, where an error will be raised). - * - * @param noWait whether lock requests should time out immediately if - * they can't be granted without waiting */ public void setNoLockWait(boolean noWait) { if (SanityManager.DEBUG) {