Le 19/03/2015 18:46, Adrian Crum a écrit :
The translation to English is not good, but I think I understand what you are saying.
Oups my apologies !

The entity values in the cache MUST be immutable - because multiple threads share the values. To do otherwise would require complicated synchronization code in GenericValue (which would cause blocking and hurt performance).

When I first starting working on the entity cache issues, it appeared to me that mutable entity values may have been in the original design (to enable a write-through cache). That is my guess - I am not sure. At some time, the entity values in the cache were made immutable, but the change was incomplete - some cached entity values were immutable and others were not. That is one of the things I fixed - I made sure ALL entity values coming from the cache are immutable.
:)  thanks Adrian for this mind refresh ! It's logical

One way we can eliminate the additional complication of cloning immutable entity values is to wrap the List in a custom Iterator implementation that automatically clones elements as they are retrieved from the List. The drawback is the performance hit - because you would be cloning values that might not get modified. I think it is more efficient to clone an entity value only when you intend to modify it.
Right. An other way would be add one step for the developper to prepare the GenericValue for update.

GenericValue party = delegator.find("Party", "partyId", partyId);
party = party.openForUpdate();
party.set("comments", "groovy");
party.store();

on list
List<GenericValue> parties : delegator.findList("Party", null, null, null, null);
for (GenericValue party : parties) {
    if (case 1) {
        party = party.openForUpdate();
party.set("comments", "groovy");
toStore.add(party);
    }
}

With : GenericValue.openForUpdate() {
     if (this.isMutable()) return this;
     return this.clone();
}

It's just a draft idea to conciliate Sys admin, dev and performance

Nicolas

Adrian Crum
Sandglass Software
www.sandglass-software.com

On 3/19/2015 4:19 PM, Nicolas Malin wrote:
Le 18/03/2015 13:16, Adrian Crum a écrit :
If you code Delegator calls to avoid the cache, then there is no way
for a sysadmin to configure the caching behavior - that bit of code
will ALWAYS make a database call.

If you make all Delegator calls use the cache, then there is an
additional complication that will add a bit more code: the
GenericValue instances retrieved from the cache are immutable - if you
want to modify them, then you will have to clone them. So, this
approach can produce an additional line of code.

I don't see any logical reason why we need to keep a GenericValue came
from cache as immutable. In large vision, a developper give information
on cache or not only he want force the cache using during his process.
As OFBiz manage by default transaction, timezone, locale, auto-matching
or others.
The entity engine would be works with admin sys cache tuning.

As example delegator.find("Party", "partyId", partyId) use the default
parameter from cache.properties and after the store on a cached
GenericValue is a delegator's problem. I see a simple test like that :
if (genericValue came from cache) {
    if (value is already done) {
       getFromDataBase
       update Value
    }
    else refuse (or not I have a doubt :) )
}
store


Nicolas

Reply via email to