Hibernate version : 3.3.0.SP1
Hello all !
I think there is a problem with asynchronous L2 cache strategies when putting data from load, as done by CacheConcurrencyStrategy.put() / EntityRegionAccessStrategy.putFromLoad() :
These methods are called immediately after the select, so that the object passed can contain uncommitted modifications. If we put it in the cache at this time (as NonstrictReadWriteCache does), and the modification is rollbacked, our cache then contains stale data.
This will happen for example if a transaction modifies database data using hql / sql, and then retrieves the data it just modified using session.load().
I was wondering if such a problem was known, and how it was supposed to be dealt with...?
Please find my suggestions below. If the solution is already well known, please ignore them :)
It seems to me that a solution would be to only 'putFromLoad' after transaction completes, with an afterPutFromLoad method. Then : - No uncommitted data is put into the cache, which solves the dirty reads problem - The transaction that did the modifications will use the first level cache, so we won't have performance issues.
That would be consistent with general asynchronous strategies behavior, which is to never put modified data into the cache until after the transaction completes.
The only problem is that the afterPutFromLoad method could override changes made by afterUpdate methods : to prevent this, we can, instead of just remove data entries invalidated by afterUpdate, put a (empty) cache entry that contains the invalidation time. Then, if putFromLoad transaction timestamp is before invalidation time, we don't do it.
|