Hi,
When working on an experiment for automatic index statistics
(re)generation, I was exposed to the Derby transaction API.
Dan filed an issue [1] suggesting to clean up this API, and I can give
my +1 to that :) In places the comments and actual usage aren't in sync,
and missing functionality of the lcc (LanguageConnectionContext) can be
obtained by working directly on the tc (TransactionController). One such
example is nested read-write user transactions, which doesn't seem to be
supported through the lcc (although the lcc API suggests so), but is
used in some places by working with the tc.
I tried to use a nested read-write user transaction to write index
statistics to the data dictionary, and was surprised to find that the
changes were lost even though I committed the transaction (they survive
if I do a proper shutdown). Turns out Derby uses the concept of
transaction contexts, and the following are defined in XactFactory:
USER_CONTEXT_ID
NESTED_READONLY_USER_CONTEXT_ID
NESTED_UPDATE_USER_CONTEXT_ID
INTERNAL_CONTEXT_ID
NTT_CONTEXT_ID
Now, the XactFactory also has this method:
/**
Decide if a transaction of this contextId needs to flush the
log when
it commits
*/
public boolean flushLogOnCommit(String contextName)
{
//
// if this is a user transaction, flush the log
// if this is an internal or nested top transaction, do not
// flush, let it age out.
//
return (contextName == USER_CONTEXT_ID ||
contextName.equals(USER_CONTEXT_ID));
}
Most of this code is rather old, so I haven't found much history. My
questions:
1) Is using a nested read-write user transaction simply wrong in this
case?
(nested because I want to release the locks on the data dictionary
as soon as possible)
2) Is the method flushLogOnCommit doing the right thing?
I haven't checked yet, but it is also important to know if the update
locks of the nested user transaction is incompatible with the parent
user transaction (to avoid deadlock when using NO_WAIT).
And thanks to Mamta for the writeup regarding the index stats issue :)
At the moment I'm trying to implement a prototype for a first step of a
hybrid solution, where the statistics generation is done in a separate
thread. The generation is initialized from the user thread when
compiling a statement, and writing new stats back is also done in a user
thread. There are several issues to resolve, but I'll see how far I get
before abandoning the approach (will attach code/comments to the
appropriate JIRA later).
Thanks,
--
Kristian
[1] https://issues.apache.org/jira/browse/DERBY-2490