Sam Brannen opened SPR-11400 and commented
Status Quo
Spring's Cache
API currently has a put(Object key, Object value)
method, but there is no form of thread-safe putIfAbsent(Object key, Object value)
method (i.e., to avoid subsequent thread-unsafe if get() == null then put()
calls).
Deliverables
- [x] Introduce a
putIfAbsent(Object key, Object value)
method inorg.springframework.cache.Cache
and corresponding implementations.
Temporary Work-around
If one needs putIfAbsent()
behavior now, consider accessing the underlying cache implementation via Cache.getNativeCache()
and then invoking putIfAbsent()
(or similar) on the native cache using the native API if available.
Affects: 3.0 GA
Comment From: spring-projects-issues
Stéphane Nicoll commented
Sam, do you need a return type for that method? that is either a boolean indicating if the value was set or the value that was already set. The reason why I am asking is that TransactionAwareCacheDecorator
would have a hard time to fulfil this contract when running as part of a transaction.
Right now the method does not return anything. Let me know if that fits with what you had in mind.
Comment From: spring-projects-issues
Sam Brannen commented
Hi Stéphane Nicoll,
Sorry about the belated reply here.
Actually, I was thinking the method could either return a boolean
flag (with true
indicating success) like with javax.cache.Cache
or the actual value like with Ehcache
and Java's ConcurrentMap
, preferably the actual value.
For example, the API for ConcurrentMap
defines the return value as follows:
Returns the previous value associated with the specified key, or
null
if there was no mapping for the key. (Anull
return can also indicate that the map previously associatednull
with the key, if the implementation supports null values.)
Maybe it's not feasible (or even possible) to return the actual value (since we support so many underlying cache implementations with differing APIs). So in the very least, I think it would be nice to return a boolean flag (again if possible).
Thanks,
Sam
Comment From: spring-projects-issues
Stéphane Nicoll commented
putIfAbsent has been added to the Cache
abstraction SPI with an Object
value that is either null
if this call associated the key in the cache or the existing object, if the key was already associated. Most cache providers do support this method signature, only the JCache API returns a boolean value. Guava returns the value that is set so there's additional logic to return the proper value.
After discussing this with Jürgen, there's no real benefit of getting a boolean (from an atomic standpoint, uses would like to get the value they have to manage).
The transaction proxy cannot support this feature properly so the Javadoc has been updated and putIfAbsent is immediately putting the value, even when a transaction is running.