Guenther Demetz (
https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%...
) *updated* an issue
Hibernate ORM (
https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiZGNmMDU3MjA1...
) / Improvement (
https://hibernate.atlassian.net/browse/HHH-16726?atlOrigin=eyJpIjoiZGNmMD...
) HHH-16726 (
https://hibernate.atlassian.net/browse/HHH-16726?atlOrigin=eyJpIjoiZGNmMD...
) Relax readability condition for strict read-write cache items. (
https://hibernate.atlassian.net/browse/HHH-16726?atlOrigin=eyJpIjoiZGNmMD...
)
Change By: Guenther Demetz (
https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%...
)
Doing some heavy load-tests using Locust we discovered that performance goes down when
multiple threads are filling 2ndLevel cache simultaneously with the same persistent
objects.
Although all threads have more or less the same transaction start timestamp, when it comes
to checking the readability of a read-write cache item, the current logic makes following
comparison:
{noformat}public boolean isReadable(long txTimestamp) {
return txTimestamp > timestamp;
}{noformat}
This implementation considers items unReadable also when the timestamp of current
transaction *equals* to the timestamp of the cached item.
*Important Update:* so this condidion considers even unReadable items which were
previously cached by the current session ({{txTimestamp == timestamp}}) ! Why distrust
ourself !?
My proposal is to change the condition to
{{ return txTimestamp >= timestamp;}}
so that a transaction which started simultaneously with the one that cached the item, can
consider valid the puts of other transactions of same age.
This has to be modified in class
org.hibernate.cache.spi.support.AbstractReadWriteAccess.java
By overriding the used region factory the user can choose which granularity he wants for
the timestamp comparison, for instance in our use-case we don’t want to go beyond
fractions of seconds.
{noformat}public class MyJCacheRegionFactory extends JCacheRegionFactory {
// UNIT SECONDS
public long nextTimestamp() {
return System.currentTimeMillis() / 1000;
}
...
}{noformat}
Applying these 2 tweaks on hibernate5.6.15 I was able to enhance the performance in
remarkable way:
100 threads accessing fresh (empty 2ndLevelCache) persistence at same time.
With
{{<property name="hibernate.cache.region.factory_class"
value="JCacheRegionFactory"/>}}
Threads ran for 14.231 ms with over 247.000 {{isReadable}} calls returning false.
{{<property name="hibernate.cache.region.factory_class"
value="MyJCacheRegionFactory"/>}}
Threads ran for 7.365 ms with 0 {{isReadable}} calls returning false.
(
https://hibernate.atlassian.net/browse/HHH-16726#add-comment?atlOrigin=ey...
) Add Comment (
https://hibernate.atlassian.net/browse/HHH-16726#add-comment?atlOrigin=ey...
)
Get Jira notifications on your phone! Download the Jira Cloud app for Android (
https://play.google.com/store/apps/details?id=com.atlassian.android.jira....
) or iOS (
https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=Em...
) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100227- sha1:28a616e )