4 Replies Latest reply on Aug 7, 2015 2:48 AM by Johannes Hoffmeister

    Reading an object from Cache while theres a lock on that

    Johannes Hoffmeister Newbie

      Hello,

       

      Im new to this forum so i hope im following the right way of asking my question. Please correct me if im doing any kind of mystake.

       

      Im using Infinispan version 5.3.0 final for my project and during running my project im seeing some unexpected behavior.

      Im having a cache with the following configuration:

       

      <namedCache name="allRequestsCache">

          <clustering mode="distribution">

            <l1 enabled="true" lifespan="60000" />

            <hash numOwners="6" />

            <sync replTimeout="200000" />

          </clustering>

          <locking lockAcquisitionTimeout="30000" concurrencyLevel="1000" useLockStriping="false" />

          <transaction autoCommit="true" transactionMode="TRANSACTIONAL" lockingMode="PESSIMISTIC" />

      </namedCache>

       

      So in my java program im having the cache as private org.infinispan.Cache <String, myRequestObject> allRequests;


      So during runtime im getting a new request in that cache. After its in the cache it gets updated a couple of times and theres no problems. But sometimes when bad timing happens im trying to read from the cache while someone else is holding a lock on it.


      What im doing exactly is :


      allRequests.get(specifickey);



      While during another process an interceptor did allRequests.lock(specifickey)


      So from the User Guide i would expect that the get Method still works and im getting the not updated object but in fact im getting null.

      So now im wondering if that is the desired behaviour? Is there any smart way to check if theres a lock on that key and wait for the lock to be completed and then read? It doesnt happen super often but quite often recently in my project.


      Is that behaviour normal or am i missing the problem?



      PS: Infinispan is running in distribution mode as you can see and 6 nodes are running. The lock/adding is done on one node and then the reading is done on another node. Is it possible that theres no "remote" get so infinispan only checks the local cache and its not available there?


        • 1. Re: Reading an object from Cache while theres a lock on that
          Radim Vansa Master

          No; reads never block unless you use FORCE_WRITE_LOCK flag (as when you call cache.getAdvancedCache().withFlags(FORCE_WRITE_LOCK).get(key)). Could you set up a test case demonstrating this behaviour?

          • 2. Re: Reading an object from Cache while theres a lock on that
            Johannes Hoffmeister Newbie

            Hi,

            Thanks for the answer. But i didnt mean that the read blocks. I mean why does the read (calling get on the cache) returns null?

            So: Does a block/write on a key results in a null result when calling get on that key at the same time? Shouldnt it take an earlier object before the lock was obtained?!

             

            Or is the problem that the key is saved on another node AND blocked so they node doesnt deliver the result?

             

            Does a read return null if the entry is on another node and not localy available and locked at that moment by another write process??

             

            Thats my problem/question. Its hard to set up a test case with multiple nodes demonstrating this i think.

            -----------------

             

            Ok i THINK i found the problem! We have the distributed cache configured a bit strange.

            We are using distributed Cache with 6 nodes and numOwners=6

            +

            getCache(cacheName).getAdvancedCache()

              .withFlags(Flag.SKIP_REMOTE_LOOKUP, Flag.SKIP_CACHE_STORE);

             

            So no remote Lookup.

             

            So it gets distributed over all nodes. But if on one node a write is started a lock is activated, then i get the null when i try a get on that key i get a null.

             

            It checks locally and its null locally? Why is not the previous value kept or is when i start a lock on one node the object removed from the cache on the other nodes??

            • 3. Re: Reading an object from Cache while theres a lock on that
              Radim Vansa Master

              Sorry, I was really answering to something a bit different than you asked.

               

              get()s are not affected by the SKIP_REMOTE_LOOKUP flag, it wouldn't make much sense to invoke them. SKIP_REMOTE_LOOKUP only affects the value returned by put(). So, get() should always return the old value.

               

              My guess is that the transaction which was writing the entry was not completed (committed), or rolled back. With transactions, the entry is really written into the cache only when the tx commits, before that all reads really return the old value (null if it was not written yet).

              • 4. Re: Reading an object from Cache while theres a lock on that
                Johannes Hoffmeister Newbie

                Ok thank you, so if onet write was successful commited on one node get should def return the (old) value if its called later even if the key is blocked for writing at the same time.

                 

                Im wondering because from the log statetement saying "starting method" to "key was null" its exactly 20 miliseconds. How is infinispan supposed to check on 6 nodes for the value in 20 miliseconds?

                 

                Its even less then 20ms since theres some other null checks and even one get on another cache in between.

                 

                For me it looks like it checks only locally and there its null for some reason. My guess at the moment is that when i start a lock for a key on one node in distributed mode, the key gets deleted from the other nodes for some reason and is only available on that node...

                 

                and since the remote look up seems not to be done...

                 

                But thats the question if it is really like this ill check more in detail and see if i can find the reason whats going on.

                 

                PS:

                SKIP_REMOTE_LOOKUP

                public static final Flag SKIP_REMOTE_LOOKUP

                When used with distributed cache mode, will prevent retrieving a remote value either when executing a get() or exists(), or to provide an overwritten return value for a put() or remove(). This would render return values for some operations (such as BasicCache.put(Object, Object) orBasicCache.remove(Object) unusable, in exchange for the performance gains of reducing remote calls.

                Note that if you want to ignore the return value of put() and you have configured a cache store you should also use the SKIP_CACHE_LOAD flag.

                 

                Flag (Infinispan Distribution 5.3.0.Final API)

                 

                But why is the key removed locally?!