Bug #9008
Trigger fired when iterating a Finalizable collection allows it to be modified
0%
History
#1 Updated by Dănuț Filimon almost 2 years ago
- File year1w.p
added - File generictest.p
added - File generictrigger.df added
- File GenericTrigger.java
added - File triggertest.p
added - File txwrapper.patch
added - File year1.df added
The main issue has been discussed in #8963-40 and #8963-44, the problem is as follows:
- When the Finalizables collection is being iterated (the TransactionManager$WorkArea.nowIterating and TransactionManager$WorkArea.op properties are set), it's possible for a trigger/generic trigger to be fired which will make it possible to reset these two properties because it will process a new external procedure (TransactionManager.processEntry() will be the first method which will reset them).
- Because the properties are again null/0, it will allow the BlockDefinition.finalizables that is being iterated to be modified and in this scenario it is possible for a generic trigger that did not open the scope of the buffer and is leaking to open it after the trigger is fired, registering the RecordBuffer to the collection of Finalizables that is being iterated causing a ConcurrentModificationException.
Attaching test files from #8963-44.
For reproducing the ConcurrectModificationException it is required to use generic triggers:- GenericTrigger.java: The generic trigger with
writewhich does nothing but does not open the scope of the buffers. - generictest.p: The startup procedure.
- generictrigger.df
- When the generictest.p external procedure finishes and ends up calling
processFinalizables(), it will end up callingGenericTrigger.write(). GenericTrigger.write()is also considered an external procedure and will callprocessEntry()which will reset thewa.nowIteratingalready set with the collection of Finalizables which ended up calling the trigger. This will reset thenowIteratingproperty to null.- After the trigger is fired and because the scope of the buffer was not opened, it will try to open it and log a warning. When the scope of the buffer is opened and because the
nowIteratingis null, it can register a new Finalizable. - Because the Finalizables collection is still being iterated and was modified, the ConcurrectModificationException is thrown.
nowIterating property is reset to null, it is enough to use a normal trigger, the files:
- triggertest.p: The startup procedure
- year1w.p: A write trigger
- year1.df
The flow is the same as for the generic trigger, with the exception of creating a new Finalizable.
The txwrapper.patch is required for both scenarios as I did not manage to flush the record when the external procedure ends (the record was flushed too early, in processBody()).
The purpose of this task is to find a method to avoid enabling resetting the nowIterating and op properties when a trigger is fired during the iteration of a Finalizables collection.
Note: The ConcurrentModificationException can't be reproduced for normal triggers because there are no leaking buffer scopes.