[
https://issues.apache.org/jira/browse/DERBY-4279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13402899#comment-13402899
]
Kristian Waagan commented on DERBY-4279:
----------------------------------------
Brett,
I think store.AutomaticIndexStatisticsMultiTest may test this scenario.
My point was not to claim that there is something wrong with the patch, but
rather to point out that I believe there is another mechanism in place that
will block DDL if a compilation is taking place. Your patch doesn't change
anything wrt that mechanism.
Now, looking at that second call to openConglomerate it seems to me it's being
done only to obtain a row location template. Only heaps can create row location
objects. A heap row location template is nothing but a Java object wrapping a
few primitive values that haven't been set. I don't immediately see why the
conglomerate/heap even has to be open to obtain such an object, but maybe the
restriction was put in place for a good reason (anyone?).
I'm optimistic that the approach in the patch is sound. The question is if
obtaining the lock can cause problems in DDL mode, and if we can skip taking it
in that mode too. However, I haven't dug deep enough to understand the locking
code. Can anyone with more experience in that area see if not taking the lock
in RCL.generateHolderMethod has consequences the code isn't prepared to handle?
> 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,
> 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