From: Olav Sandstaa Date: November 24 2008 3:25pm Subject: Question about Transaction::getRelativeState called with null values List-Archive: http://lists.mysql.com/falcon/206 Message-Id: <492AC783.6090807@sun.com> MIME-Version: 1.0 Content-Type: text/plain; format=flowed; charset=ISO-8859-1 Content-Transfer-Encoding: 7BIT Hi Kevin, After applying your patch for Bug #40893 "Falcon concurrent unlock can cause invalid fetches" I found another issue with the use of Transaction::getRelativeState() that I first thought had to be wrong but which might be correct anyway. It would be good to get your comment on it. It is related to the following code: State Transaction::getRelativeState(Transaction *transaction, TransId transId, uint32 flags) { if (transactionId == transId) return Us; // A record may still have the transId even after the trans itself has been deleted. if (!transaction) { // All calls to getRelativeState are for the purpose of writing. // So only ConsistentRead can get CommittedInvisible. if (IS_CONSISTENT_READ(isolationLevel)) { // If the transaction is no longer around, and the record is, // then it must be committed. if (transactionId < transId) return CommittedInvisible; // Be sure it was not active when we started. for (int n = 0; n < numberStates; ++n) if (states [n].transactionId == transId) return CommittedInvisible; } return CommittedVisible; } After your fix I had hoped that we no longer should see cases where we use the states array in the last for-loop. But with the debug code I had in my code tree we were still executing that code (but not the return statement). So I wondered why.... It turns out that the case where this code is executed happens when we call Transaction::getRelativeState(Transaction*...) and the transaction argument is NULL and the transId is 0. This seems to happen when we calls Transaction::getReleativeState(Record* ) and the record argument is a Record object, not a RecordVersion object. When this is the case, Transaction::getRelativeState() will always return CommittedVisible (which is likely the correct value). Still from reading the above code it is a bit hard to imagine that it is supposed to work when both transaction==NULL and transId==0 (and could easily be a source for introducing unintended changes if someone decided to change the order of the logic). At least this puzzled me, so is it correct use of Transaction::getTransaction(NULL, 0, flags) in this case? Olav