Re: Managing EOF caching
Re: Managing EOF caching
- Subject: Re: Managing EOF caching
- From: Art Isbell <email@hidden>
- Date: Thu, 19 Jan 2006 12:53:21 -1000
On Jan 19, 2006, at 11:54 AM, Michael DeMan wrote:
You are correct on blowing away your editing contexts impacting
performance heavily. Of course, the other side of the coin is that
if you never do that over time EOF will try to cache the entire
database in RAM...
Actually, EOF will cache only those snapshots that are referenced
from an editing context. When the last reference is eliminated, the
snapshot is freed. Because of this, I have never nuked snapshots
explicitly. Instead, I have created multiple editing contexts, one
for objects that need to persist and another for those that don't.
When I've saved all objects in the temporary editing context, I get
rid of that editing context which will automatically free all
snapshots that aren't referenced from the persistent editing
context. Of course, the JVM is responsible for actually freeing up
memory which might not occur as soon as one would like.
#1. Review your EOModel and make sure you are locking only on
columns you need to. On fresh applications I've always put in a
dateLastUpdated column in each object and lock only on that.
This will accelerate updates and deletes because the generated
"WHERE" clause will contain each column whose attribute is used for
locking plus the primary key columns. By locking only on
dateLastUpdated, the number of columns for which the database must
compare values is minimized.
However, beware of precision problems that can exist with some
databases when using timestamp attributes for locking. These
problems will cause update and delete failures that don't make sense.
There is overhead in EOF with the snapshot code in locking. I'm
not 100% sure, but I think the snapshot only tracks the columns
that you have marked as used for locking in your model.
This will save your memory in your snapshot and and reduce the
overhead in saveChanges() when EOF has to review the current data
against the snapshot.
I think you mean class attributes. Snapshots contain all class
attributes plus the primary key. Attributes used for locking don't
affect snapshots.
You can actually add this code to your GenericRecord super class
and add the column to all your tables on the fly, and defaulting
the column to NULL if 3rd party applications are inserting into the
database. If 3rd party apps are updating other columns live, then
you''ll have to keep those as locked columns anyway though.
public void validateForSave() throws
NSValidation.ValidationException ()
if (dateLastUpdated()==null) setDateLastUpdated(new
NSTimestamp());
... do rest of validation...
}
I believe that the above code will update dateLastUpdated in EOs
with no actual changes. Any EO in which an attribute or to-one
relationship has been set will be marked as updated even when the new
values are identical to the old values. No SQL would be generated
normally, but because you have actually updated dateLastUpdated, the
database will be needlessly updated.
To make this work correctly can be tricky and can depend on whether
you are viewing this from the point of view of attributes and
relationships or columns and foreign keys.
You need to examine updatedObject.changesFromSnapshot
(editingContext.committedSnapshotForObject(updatedObject)). If this
is an empty dictionary, no actual changes have occurred, so
dateLastUpdated shouldn't be updated.
If a to-one relationship value has actually changed, then
updatedObject's foreign key value has also changed, so
dateLastUpdated should be updated.
However, if only a to-many relationship array has changed, no SQL
update statement for updatedObject will be generated because only
foreign keys in relationship destination objects have been updated,
so updatedObject.dateLastUpdated shouldn't be updated. Others may
consider updatedObject to be updated because one of its to-many
relationships has been updated, so in this case,
updatedObject.dateLastUpdated should be updated. I take the former
point of view.
I'm composing this from memory, so someone please correct me if I
don't have this exactly right.
#3. As you are doing now, review each and every place that you do
invalidateAllObjects() or whatever else that blows away the data.
invalidateAllObjects() is a sledge hammer that can cause more
problems than it solves. I have always found a better approach.
Aloha,
Art
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden