I'm working on an app that gets a collection from a single Hibernate session and uses it, in read-only fashion, across many threads in a Terracotta cluster. (E.g., our perf tests hammer on this object with 20k users simultaneously.)
I've seen many posts here explaining that sessions are not threadsafe and that it is necessary to add synchronization code in the client if one is so unfortunate or misled as to desire concurrent access.
Lazy loading means that even if the access pattern is read-only, collection access must be synchronized. But simply wrapping synchronized blocks around the collection is not performant, because all other threads block every time one of them wants to do a read.
With a bit of exploration of the persistent collection code we found it was not too hard to insert read/write locks such that the integrity of lazy loading is preserved, but read operations can execute concurrently after initialization is complete. A side benefit of using read/write locks is that it is easy to switch off the locking, on an instance by instance basis if needed, in situations where concurrency is not desired. In principle it could be controlled by an annotation, though we did not go that far.
As an example of our motivation: we saw latencies in our load test app go from 4 seconds to 20 milliseconds, when we replaced client-level synchronization with finer grained read/write locking inside the collections.
I am wondering if others have tried this experiment, and whether there is interest within the Hibernate community in pursuing this?
|