Bug #11279
RecordNursery invalidated for a rollabacked transient record
0%
Related issues
History
#1 Updated by Eduard Soltan 5 months ago
start.p
routine-level on error undo, throw.
define temp-table ttTest
no-undo
field testNum as integer.
def buffer bTtTest for ttTest.
run test33.p (input-output table ttTest by-reference) no-error.
find first bTtTest no-error.
message "finally" available bTtTest.
test33.p
routine-level on error undo, throw.
define temp-table ttUndoTest
no-undo
field testNum as integer.
define buffer bTtUndoTest for ttUndoTest.
define input-output parameter table for ttUndoTest.
do transaction on error undo, throw:
create ttUndoTest.
ttUndoTest.testNum = 5.
undo, return.
end.
Lets analyse what happens in test33.p procedure. I create a new ttUndoTest record, because we are in DO TRANSACTION block the temp-table record will not not be flushed but will be added to RecordNursery.newRecords map. In this way it will be found using a separate buffer even before the actual flush to the database.
Now I do a undo, return with a temp-table that is NO-UNDO, this means that the record is still retained in the buffer even after rollback. However the transaction block ends, and RecordNursery.clear method is called and the transient record is deleted from RN.newRecords.
From now on a separated buffer can't find the record before the actual release happens, however in OE this is still possible.
#2 Updated by Eduard Soltan 5 months ago
- Related to Feature #9545: confirm/add table parameter support added
#3 Updated by Alexandru Lungu 5 months ago
Now I do a undo, return with a temp-table that is NO-UNDO, this means that the record is still retained in the buffer even after rollback.
Ah, this happens because it is NO-UNDO. RecordNursery.clear should clear only undo records ... but at the same time, keeping no-undo indefinably long is still dangerous. I think that maybe the transaction block end should clear the undo records and flush the other ones.
PS: there is an inherent mismatch in FWD vs OE because temporary records are not flushed to dirty, but directly in _temp. This means that per-index visibility of records that are transient is not completely possible. If you do a look-up on index 1 that is complete, you will flush the record. Then, if you do a look-up index 2, then it will find it, even if it shouldn't have been visible. This may hint that dirty may be required for _temp, but this was too much of a performance drawback. In #8388 it may be possible, but I did not invest much time investigation UNION ALL queries for temp.