db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Mamta A. Satoor (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (DERBY-4279) Statement cache deadlock
Date Fri, 29 Jun 2012 19:42:43 GMT

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

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

I am not familiar with the synchronization code during stale prepared statement re-compile.
But I was looking at the first patch submitted by Brett and suggestion by Knut about statements
using session schema and how they do not get saved in the statement cache. 

I worked on statements involving session schema many years back and recall implementing logic
which will prevent such statements from going into statement cache. 

Will a similar logic for this jira help with all the synchronization issues we are dealing
with? ie, if a thread finds that the prepared statement is already in cache but it is being
compiled by another thread, then go ahead and create a new GenericPreparedStatement and compile
that instead(same as if the statement never existed in the cahce), BUT do not save this new
statement in the statement cache(just like a statement referencing session schema). So, this
newly compiled statement will not be available to any other thread. But that should be fine
because original preapred statement in the cache is already getting compiled and hence it
will be available to other threads in future. Like Brett mentioned, "Unless a statement undergoes
constant concurrent recompilation (defeating the statement cache anyway)", throwing away a
compiled statement after use by a thread if that thread finds previously compiled statement
in invalid state and getting compiled by another thread should not be a big overhead.

I am not sure if creating a GenericPreparedStatement for use by just one thread will solve
the synchronization problem in this jira but I wanted to put it out anyways in case if this
approach helps.
                
> Statement cache deadlock
> ------------------------
>
>                 Key: DERBY-4279
>                 URL: https://issues.apache.org/jira/browse/DERBY-4279
>             Project: Derby
>          Issue Type: Bug
>          Components: SQL
>    Affects Versions: 10.0.2.1, 10.1.3.1, 10.2.2.0, 10.3.3.0, 10.4.2.0, 10.5.1.1, 10.8.1.2
>         Environment: Windows Vista, OS X 10.5+
>            Reporter: Jeff Stuckman
>              Labels: derby_triage10_5_2
>         Attachments: Derby4279.java, client_stacktrace_activation_closed.txt, no-lock-experiment.diff,
patch4279.txt, patch4279_2.txt, stacktrace.txt
>
>
> Due to a design flaw in the statement cache, a deadlock can occur if a prepared statement
becomes out-of-date.
> I will illustrate this with the following example:
> The application is using the embedded Derby driver. The application has two threads,
and each thread uses its own connection.
> There is a table named MYTABLE with column MYCOLUMN.
> 1. A thread prepares and executes the query SELECT MYCOLUMN FROM MYTABLE. The prepared
statement is stored in the statement cache (see org.apache.derby.impl.sql.GenericStatement
for this logic)
> 2. After some time, the prepared statement becomes invalid or out-of-date for some reason
(see org.apache.derby.impl.sql.GenericPreparedStatement)
> 3. Thread 1 begins a transaction and executes LOCK TABLE MYTABLE IN EXCLUSIVE MODE
> 4. Thread 2 begins a transaction and executes SELECT MYCOLUMN FROM MYTABLE. The statement
is in the statement cache but it is out-of-date. The thread begins to recompile the statement.
To compile the statement, the thread needs a shared lock on MYTABLE. Thread 1 already has
an exclusive lock on MYTABLE. Thread 2 waits.
> 5. Thread 1 executes SELECT MYCOLUMN FROM MYTABLE. The statement is in the statement
cache but it is being compiled. Thread 1 waits on the statement's monitor.
> 6. We have a deadlock. Derby eventually detects a lock timeout, but the error message
is not descriptive. The stacks at the time of the deadlock are:
> This deadlock is unique because it can still occur in a properly designed database. You
are only safe if all of your transactions are very simple and cannot be interleaved in a sequence
that causes the deadlock, or if your particular statements do not require a table lock to
compile. (For the sake of simplicity, I used LOCK TABLE in my example, but any UPDATE statement
would fit.)

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

       

Mime
View raw message