6 Replies Latest reply: Jan 29, 2012 2:49 PM by Sanne Grinovero RSS

Dirty reads may occurs on mutable objects

Avner Sternheim Newbie

Hi,

 

I found a documented bug on dirty reads on mutable objects :

https://issues.jboss.org/browse/ISPN-1345

 

and I have couple of questions regarding it.

 

1. Do you know if it happen in older versions than 5.0

2. According to this bug, it seems that the most common use with transactional cache is immutable objects, am I right?

cause otherwise a lot of people would have complained about this bug.

3. is there a work around to this issue?

 

thanks,

Avner

  • 1. Re: Dirty reads may occurs on mutable objects
    Sanne Grinovero Master

    Hi Avner,

    correct, Infinispan on a single node acts as a ConcurrentHashMap, so if multiple threads get the same object (as identified by same key) they are likely to receive the same instance.

    For obvious reasons different nodes will have different instances, and because of the serialization layer even on the same node it might happen to receive different instances of the same value; but these are details one should not rely on, so storing immutable objects is recommended.

     

    You can still store mutable objects, just make sure your application makes defensive copies before making changes on them.

     

    3. No there is no other workaround (other than making defensive copies). Feel free to ask for it as a feature request on JIRA, it should be easy to implement but beware Infinispan will need to reuse the serialization strategies, your application can possibly be smarter in terms of performance.

  • 2. Re: Dirty reads may occurs on mutable objects
    Avner Sternheim Newbie

    Hi Sanne,

     

    thanks for your answer.

    If I understnad you correctly, it's happen also in previous versions.

     

     

  • 3. Re: Dirty reads may occurs on mutable objects
    Avner Sternheim Newbie

    one more question - we are talking about transactional cache.

    so although it's transactional and suppose to be ACID it doesn't - cause it cause dirty reads on mutable objects, right?

  • 4. Re: Dirty reads may occurs on mutable objects
    Sanne Grinovero Master
    If I understnad you correctly, it's happen also in previous versions.

    Yes, this is always been the case.

     

    so although it's transactional and suppose to be ACID it doesn't - cause it cause dirty reads on mutable objects, right?

    Yes this applies to transactional caches as well. You should not use mutable objects if you need this guarantees; if you don't like this, as mentioned it's easy to add an option to make copy-on-reads, just open a feature request on JIRA. But that would apply to all reads of such an option was enabled, so I'd be interested to know if you would really like such an option as personally as a user I wouldn't like to sacrifice that performance.

  • 5. Re: Dirty reads may occurs on mutable objects
    Dan Berindei Apprentice

    Sanne Grinovero wrote:

     

    3. No there is no other workaround (other than making defensive copies). Feel free to ask for it as a feature request on JIRA, it should be easy to implement but beware Infinispan will need to reuse the serialization strategies, your application can possibly be smarter in terms of performance.

     

    @Sanne, doesn't Infinispan already create new instances when reading data with storeAsBinary enabled?

  • 6. Re: Dirty reads may occurs on mutable objects
    Sanne Grinovero Master

    @Dan, look into org.infinispan.marshall.MarshalledValue.get() : yes it is *likely* going to create a new instance on read, but race conditions on get might return the same instance. A get() operation is non-blocking if it finds another value in instance-form; if not it deserializes it and a lock is acquired only to prevent two threads from doing the same deserialize work at the same time to avoid duplicate deserialization work and return the same instance.

     

    So it's designed for speed, and the option should not be used to get independent instances as that's a non-guaranteed side-effect - even though, you're right in that it's very likely a different instance! But this would be more likely with expensive deserialization operations and certain usage patterns.

     

    This doesn't seem too hard to change; we could support a stronger guarantee for certain configurations (as an alternative option, I wouldn't apply it for all cases). I would also like to see an option for the opposite: keep the value in instance-form for longer, to benefit more from reuse in those cases for which the cost of deserialization is worth the extra memory.