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

Reply via email to