From: Olav Sandstaa Date: November 18 2008 3:03pm Subject: New dependency manager and Transaction::getRelativeState List-Archive: http://lists.mysql.com/falcon/192 Message-Id: <4922D934.1060009@sun.com> MIME-Version: 1.0 Content-Type: text/plain; format=flowed; charset=ISO-8859-1 Content-Transfer-Encoding: 7BIT Jim and everybody else, As I mentioned in was working on removing the last parts of the old dependency manager and had one issue left (famous last word :-) ). This issue is related to Transaction::getRelativeState(). Some background: The new dependency manager stores the event counter for (a) when the transaction became active and (b) when the transaction committed in the transaction object. These two event numbers is then used for comparing the relative state of active and committed transactions. Using these instead of the old dependency manager allows me to remove (a) the dependency counter for each transaction and (b) the states array with pointers to all transactions that where active at the start of a given transaction. The issue: The code for the first part of Transaction::getRelativeState() looks like this: 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; } The issue is related to when the pointer to the transaction argument is NULL: 1) Not having a reference to the transaction makes it hard(er) to compare the state of two different transactions since the one we are going to compare state against is "not there". For the old dependency manager this was easy since it has the states array of all active transactions available also after these transactions possibly are deleted (see the for loop above). But with the new dependency manager we should be able to remove this state array.... I have a working solution for this: By including the commit transition event number in every RecordVersion object (I set this in Transaction::commit()) makes it possible to compare this record against this transaction's start event. The code replacing the above for loop looks approximately like this: if (transEndEvent_of_recordObject > startEvent) { fprintf(stderr, "T::getRelativeState: %d: NEW: CommittedInvisible: end=%d start=%d\n", transactionId, transEndEvent, startEvent); return CommittedInvisible; } The test for this is simple but I do not like to having to include the commit event in record versions if I do not have to do so. Anyone having a suggestion for a better solution? 2) Comments in the code above seems to suggest that the reason for not having the pointer to the transaction object is due to that the transaction object has been deleted and it assumes that the transaction has been committed. In my testing this seems not like it is an correct assumption, in most cases when the transaction pointer is NULL the transaction is actually still in Active state. Questions: a) Are the comments in the code wrong? Or b) The code is wrong? And c) Why do we not have the transaction pointer pointing to the transaction if it is still active or (d) I have I introduced some error that causes this? Any comments or feedback is appreciated. Olav