[ 
https://issues.apache.org/jira/browse/IGNITE-5030?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15978260#comment-15978260
 ] 

Vyacheslav Daradur commented on IGNITE-5030:
--------------------------------------------

bq. @Cacheable(sync=true) guarantee that only one thread (across the cluster) 
will fetch value for a key on get, even in case of some simultaneous gets.
The main idea is using EntryProcessor to provide such guarantee.
{code}
IgniteCache#invoke(K key, EntryProcessor<K, V, T> entryProcessor, Object... 
arguments)
{code}
It works well when we call #invoke directly.
But, there is an issue when using @Cachable(sync = true) with a cluster with 2+ 
nodes.

The main reason of the issue is that "args0" (in the code below) is an instance 
of CacheAspectSupport$1, 
which  can't be deserialized properly at another node after a transfering, 
because it contains classes wich are generated runtime by JVM.
{code}
class ValueLoaderEntryProcessor<T> implements CacheEntryProcessor<Object, 
Object, T> {
        @Override public T process(MutableEntry<Object, Object> entry, 
Object... args) throws EntryProcessorException {
            
             Callable<T> valueLoader = (Callable<T>)args[0];

            // working logic according to the documentations
        }
    }
{code}

Another solutions is using a lock on a key, for example:
{code}
    @Override public <T> T get(Object key, Callable<T> valueLoader) {
        Object val = cache.get(key);

        if (val != null)
            return (T)fromStoreValue(val);

        Lock lock = cache.lock(key);
        try {
            lock.lock();

            try {
                val = valueLoader.call();
            }
            catch (Exception e) {
                throw new ValueRetrievalException(key, valueLoader, e);
            }

            if (val != null)
                cache.put(key, val);
        }
        finally {
            lock.unlock();
        }
}
{code}
But it works only with TRANSACTIONAL atomicity mode.

> Support Spring @Cacheable(sync=true) annotation
> -----------------------------------------------
>
>                 Key: IGNITE-5030
>                 URL: https://issues.apache.org/jira/browse/IGNITE-5030
>             Project: Ignite
>          Issue Type: Task
>            Reporter: Anton Vinogradov
>            Assignee: Vyacheslav Daradur
>
> @Cacheable(sync=true) guarantee that only one thread (across the cluster) 
> will fetch value for a key on get, even in case of some simultaneous gets.
> So, 
> org.apache.ignite.cache.spring.SpringCache#get(java.lang.Object, 
> java.util.concurrent.Callable<T>) 
> should be implemented to provide such guarantee.



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

Reply via email to