[ 
https://issues.apache.org/jira/browse/DERBY-1848?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12602064#action_12602064
 ] 

Mamta A. Satoor commented on DERBY-1848:
----------------------------------------

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).

> jdbcapi/SetQueryTimeoutTest.java fails on IBM  wctme 5.7
> --------------------------------------------------------
>
>                 Key: DERBY-1848
>                 URL: https://issues.apache.org/jira/browse/DERBY-1848
>             Project: Derby
>          Issue Type: Test
>          Components: Regression Test Failure
>    Affects Versions: 10.2.2.1, 10.3.1.4, 10.5.0.0
>         Environment: Windows
>            Reporter: Rajesh Kartha
>            Assignee: Mamta A. Satoor
>         Attachments: DERBY_1848_Repro.java, DERBY_1848_Repro.java
>
>
> The following is the diff:
> *** Start: SetQueryTimeoutTest jdk1.3.1 subset - 2.2 derbyall:jdbcapi 
> 2006-09-10 11:07:05 ***
> 7 del
> < Statement 1 completed
> 8 del
> < Statement 2 completed
> 9 del
> < Statement 3 completed
> 10 del
> < Testing timeout with an execute operation
> 11 del
> < Statements that should time out timed out, and statements that should 
> complete completed
> 12 del
> < Testing setting a negative timeout value
> 13 del
> < Negative timeout value caused exception, as expected
> 14 del
> < Execute returned a ResultSet
> 15 del
> < Testing that Statement remembers timeout.
> 16 del
> < Testing that PreparedStatement remembers timeout.
> 17 del
> < Testing that CallableStatement remembers timeout.
> 18 del
> < Testing timeout with executeUpdate call.
> 19 del
> < Test SetQueryTimeoutTest PASSED
> 19a7,11
> > Test SetQueryTimeoutTest FAILED
> > org.apache.derbyTesting.functionTests.tests.jdbcapi.SetQueryTimeoutTest$TestFailedException:
> >  Unexpected exception in 1: java.sql.SQLException: The statement has been 
> > cancelled or timed out.
> > ERROR XCL52: The statement has been cancelled or timed out.
> > java.sql.SQLException: Invalid transaction state.
> > java.sql.SQLException: Invalid transaction state.
> Test Failed.
> *** End:   SetQueryTimeoutTest jdk1.3.1 subset - 2.2 derbyall:jdbcapi 
> 2006-09-10 11:07:26 ***

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to