L2 entity cache is evicted prior to committing transaction for HQL/native updates
Description
Activity
balram patel May 4, 2022 at 10:12 AM
This fix leads to https://hibernate.atlassian.net/browse/HHH-15247
Frank Doherty December 21, 2019 at 7:34 AM
I have created a pull request here: https://github.com/hibernate/hibernate-orm/pull/3152
It includes some func tests (update and delete for HQL/native queries) which:
confirmed the problem (they are failing when run without the suggested fix)
are passing when the suggested fix is included
Frank Doherty December 21, 2019 at 6:59 AM
It looks like the BulkOperationCleanupAction.EntityCleanup
constructor (called during the transaction) is calling cacheAccess.removeAll( session );
In the case of EntityReadWriteAccess
this invokes the removeAll
method inherited from AbstractCachedDomainDataAccess
, which does:
getStorageAccess().clearCache( session );
So the cache is cleared here before the transaction is committed.
Also note that the release
method inBulkOperationCleanupAction.EntityCleanup
(called after the transaction is committed) calls cacheAccess.unlockRegion( cacheLock );
In the case of EntityReadWriteAccess
this is a no-op.
(One possible approach might be to change EntityReadWriteAccess
so that removeAll
is the no-op and unlockRegion
performs the cache eviction.)
This issue occurs when using a read-write cache concurrency strategy, and applying an update or delete as part of an HQL or native sql query.
The L2 entity cache gets cleared before the transaction is committed.
This can lead to scenarios where a different session is able to populate the cache with the old data, leaving the cache out-of-date.