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