Return-Path: Delivered-To: apmail-db-derby-dev-archive@www.apache.org Received: (qmail 90914 invoked from network); 3 Jun 2008 20:50:28 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 3 Jun 2008 20:50:28 -0000 Received: (qmail 93284 invoked by uid 500); 3 Jun 2008 20:50:30 -0000 Delivered-To: apmail-db-derby-dev-archive@db.apache.org Received: (qmail 93245 invoked by uid 500); 3 Jun 2008 20:50:30 -0000 Mailing-List: contact derby-dev-help@db.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: Delivered-To: mailing list derby-dev@db.apache.org Received: (qmail 93234 invoked by uid 99); 3 Jun 2008 20:50:30 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 03 Jun 2008 13:50:30 -0700 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: domain of msatoor@gmail.com designates 209.85.198.224 as permitted sender) Received: from [209.85.198.224] (HELO rv-out-0506.google.com) (209.85.198.224) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 03 Jun 2008 20:49:41 +0000 Received: by rv-out-0506.google.com with SMTP id f6so1582886rvb.55 for ; Tue, 03 Jun 2008 13:49:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from:to:subject:mime-version:content-type:content-transfer-encoding:content-disposition; bh=OHjucBy1Xs1qqV/PBtrBjtmCaWelKHSbxvcBT3h8kKA=; b=Rfs5RKnMvOXaFtN6225BY0aLbINVDpV3kgn8Rw8w7Z2rSGiVRbBfeFC/E4ZOVjD7/de8jpWCsWcvun5AgeJpR3049eNWiRtX2/v83q/lU2SoHXL9DjnckCaMKQ3JoJke9KKk3e0U1Cotn5qBn2B8a+T/uSB1sarznyDpqXon6xk= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:to:subject:mime-version:content-type:content-transfer-encoding:content-disposition; b=uk6vXZ5bNyPh1D1anQ8Z6v9i5FjfNUWH8UBmFQS+KDUBFeXxAWz2FO6rGufHTXh0Du4kZnw4+UloHdD9Rrttm843LnXXNsWg8f9yn2v6wH2Ga3hDLCqhgWoEgsOS8MDLlsrGcmj4xzshU4CnIsjWIsRMr7UhUkixV3v2OUZ6J5k= Received: by 10.140.249.20 with SMTP id w20mr6155897rvh.103.1212526198213; Tue, 03 Jun 2008 13:49:58 -0700 (PDT) Received: by 10.141.26.11 with HTTP; Tue, 3 Jun 2008 13:49:58 -0700 (PDT) Message-ID: Date: Tue, 3 Jun 2008 13:49:58 -0700 From: "Mamta Satoor" To: "Derby Development" Subject: How is Statement.setQueryTimeout implemented in Derby? MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline X-Virus-Checked: Checked by ClamAV on apache.org Hello, While researching the random behavior of DERBY-1848, I looked through the Derby code to understand how we implement Statement.setQueryTimeout and following is what I found out. I would appreciate if someone can verify if my understanding is correct or not. And if yes, then why under weme6.1, we might not be disabling the timer associated with Statement.setQueryTimeout implementation? Will appreciate any feedback. Thanks Around each position moving request on a ResultSet object (next/previous/first/last etc), Derby pushes the StatementContext for that Statement (EmbedResultSet.movePosition). And once the ResultSet positioning is over, the StatementContext is popped back. This happens in EmbedResultSet.moveposition(int,int,String) method. During the pushing of the StatementContext (in GenericLangaugeConnectionContext.pushStatementContext), we mark the StatementContext to be in use by calling GenericStatementContext.setInUse. This setInUse method checks if query timeout is set on the Statement, and if yes, then it starts a Timer which uses CancelQueryTask to keep track of when the Statement execution should be marked timedout (The setting of the CancelQueryTask happens in GenericStatementContext.setInUse). Once the requested positioning is done on the ResultSet object, Derby goes through the process of popping the StatementContext. This happens in GenericLangaugeConnectionContext.popStatementContext. Here, we mark the StatementContext as not in use since we are going to pop the StatementContext. This work gets done in GenericStatementContext.clearInUse. clearInUse checks if there is a timeout timer associated with the StatementContext (this association was done in pushStatementContext) and if yes, then it disassociates the timer and then marks the timer object as null. It also goes ahead and marks the cancel query flag to flase (cancellationFlag). The cancellationFlag tells whether the query associated with the StatementContext has exceeded the timeout limit. If user never set a query timeout on the Statement object, cancellationFlag will always be false. But if the user has set a query timeout, then this flag will be set to true by the CancelQueryTask when it finds that the Statement has run over it's limit of timeout amount. We do not throw an exception for query timeout as soon as the flag gets set to true. The cancellationFlag gets checked only when the user has requested a position movement on the ResultSet object. So, one possible scenario can be that we push a StatementContext because user has requested say, ResultSet.next. During push, we set a query timeout timer because user has requested for timeout on the query. Then we go through the code for moving to next row in the ResultSet. The first thing we check there is if the query is marked cancelled (by checking cancellationFlag on StatementContext). If yes, then we throw an exception. But for this case, let's assume the query has not timeed out yet. Hence we go through the rest of the code for moving to next row. While we are doing this(ie before we are finished with the code for moving to next row), say the timer times out and the timer goes and sets cancellationFlag to true (this happens in CancelQueryTask.run() which lives in the class GenericStatementContext). But this setting of flag is little too late for the current movement within the ResultSet object because we had just checked the flag earlier and it was set to false at that time. So, at this point, we just finish the ResultSet movement and then pop the StatementContext without throwning any exception. If the user has asked for another ResultSet movement after the current one, we will catch the query timeout, go through popping the current Statement Context and then throw an exception. The popping of the StatementContext marks the StatementContext associated with the query timeout timer to false and then it nullifies the query timeout timer. What seems to be happening in case of weme6.1 occassionally is that once the query timeout has been set and detected (which causes us to nullify the CancelQueryTask associated with the StatementContext being popped and throw exception), Derby somehow manages to set the query timeout to true again and we end up detecting it again and apparently we associate that timeout with a StatementContext that has not even requested a query timeout on it. I wondered if someone familiar with this query timeout code can see what can cause us to set the timeout again when apparently we have nulled out the timer (in GenericLangaugeConnectionContext.popStatementContext).