Project

General

Profile

Bug #11552

Stale data with write trigger.

Added by Eduard Soltan about 1 month ago. Updated about 1 month ago.

Status:
New
Priority:
Normal
Assignee:
-
Target version:
-
Start date:
Due date:
% Done:

0%

billable:
No
vendor_id:
GCD
case_num:
version_reported:
version_resolved:
reviewer:
production:
No
env_name:
topics:

History

#1 Updated by Eduard Soltan about 1 month ago

Lets suppose we will have a buffer scoped to transactional block. As finalizables of this block the will be registered SavepointManager 's, and the RecordBuffer. The table does have a write trigger registered.

doBlock:
do transaction:
   ...
   book.isbn = 5.
   ...
end.

Please note the I tested this in a multi-user scenario.

During this block execution (in TM.processValidate) the buffer became stale: does not pass the Session.save stale check (sharedVersion and dmo.version does not match). State of the record gets modified to STALE, but remains marked as CHANGED.

After the doBlock execution, in TM.popScope the finalizables are processed. finish and delete method of SavepointManager are called before RecordBuffer. Call of RB.delete fires the write trigger. In SavepointManager.prepareBlock, the parentBlock will be set to null, even though the doBlock is a transactional block.

This will cause later on the NPE in SavepointManager.commit:

java.lang.NullPointerException: Cannot invoke "com.goldencode.p2j.persist.orm.SavepointManager$Block.rollUp(com.goldencode.p2j.persist.orm.SavepointManager$Block)" because "this.parentBlock" is null
    at com.goldencode.p2j.persist.orm.SavepointManager.commit(SavepointManager.java:344)
    at com.goldencode.p2j.util.TransactionManager.processCommitImpl(TransactionManager.java:7196)
    at com.goldencode.p2j.util.TransactionManager.processCommit(TransactionManager.java:7147)
    at com.goldencode.p2j.util.TransactionManager.popScope(TransactionManager.java:4862)
    at com.goldencode.p2j.util.TransactionManager$TransactionHelper.popScope(TransactionManager.java:9218)
    at com.goldencode.p2j.util.BlockManager.topLevelBlock(BlockManager.java:9417)
    at com.goldencode.p2j.util.BlockManager.externalProcedure(BlockManager.java:704)

#3 Updated by Constantin Asofiei about 1 month ago

Eduard, do you have a standalone test for this? Or these are just observations from debugging?

#4 Updated by Eduard Soltan about 1 month ago

Constantin Asofiei wrote:

Eduard, do you have a standalone test for this? Or these are just observations from debugging?

No, I don't have a stand alone test for this. I noticed it during debugging on a multi user environment. For sure, in this specific case it does not happen with just a single user. version in BaseRecord is smaller then sharedVersion number (this makes the dmo stale), which is modified by another user.

#5 Updated by Ovidiu Maxiniuc about 1 month ago

I tried to track it back, but something is missing. A link.

The doBlock itself will not mark the record as STALE, just CHANGED. Clearly, a second context probably altered the version of the record so that when the transaction block ends the Session.save() gets aware of the event.

Is this happening consistently? Because it looks to me that a very strict scenario is necessary for this to occur.

#6 Updated by Eduard Soltan about 1 month ago

Ovidiu Maxiniuc wrote:

The doBlock itself will not mark the record as STALE, just CHANGED. Clearly, a second context probably altered the version of the record so that when the transaction block ends the Session.save() gets aware of the event.

Is this happening consistently? Because it looks to me that a very strict scenario is necessary for this to occur.

When run with multiple users, indeed it happen consistently. I am trying to reproduce with a small test case with just 2 users.

Also available in: Atom PDF