Re: locking problem
Re: locking problem
- Subject: Re: locking problem
- From: Ben Trumbull <email@hidden>
- Date: Sun, 19 Dec 2004 16:08:43 -0800
At 17:50 -0500 12/19/04, Nathan Dumar wrote:
If I replace dispose with reset, I get the previously mentioned error.
I guess it would be more accurate to say that I can't re-use a
handle? or pointer? if I use reset.
That's odd. Looks like a bug in WO.
Keeping EOs around means there is still a hard reference to your
EC. So your ECs won't get garbage collected, so your app will leak
a lot of memory.
I'm not sure this applies here. How do you mean keeping them around?
If you have a reference to any EO you ever got from an EC, you'll
indirectly have a hard reference to that EC. So it'll never get gc'd.
Okay, I can try that. I make an EC and I do a bunch of stuff in it
(making objects, saving, etc). If I don't dispose the EC when I'm
done with it, and I move on and do other stuff in other components,
then other editing contexts from other sessions can't see the newly
created objects (can't see the info in the database) until that
first ec finally gets garbage collected. Fetches for other ECs in
other sessions will not return the new objects as long as the EC
that created them still exists (aka stale data).
First, have you actually saved the EC ? Just checking.
Have you tried changing your fetches to have an EOFetchSpecification
with setRefreshesRefetchedObjects(true) ?
Also, consider trying, in Session awake() to set the EC's
setFetchTimestamp() to System.currentTimeMillis()
In reading a discussion thread about ERXEC recently, Anjo said that
ERXEC only locks during the "dangerous" operations, like save,
fetch, etc. So, that's what I'm doing now -- putting locks in the
try block, before any fetch or save, and unlocking right after, in
the finally block. From what I've read, this seems to be the best
solution, but I'm always open to learn more. If anyone has
suggestions, ideas, warnings, or whatever, please post.
All operations are "dangerous". Just because an operation *looks*
like it should not cause multithreading problems to you doesn't make
it safe in reality.
Take reading a value from an EO's attribute. What if the EO is a
fault ? A database operation has to occur to populate the EO. So
the database resources need to be locked. Caches need to be updated.
Okay, so then you check if an EO is a fault before reading. But if
you follow keypath through a relationship, and the related EO is a
fault ...
There are no read only operations.
Everything you do with EOF has cache coherency implications.
But let's veer into a hypothetical land in which every EOF method is
synchronized. No more locking! How cool! So, we can have a bunch
of threads all working with an EC. Changing objects. Inserting
objects. Faulting objects into memory with different amounts of
staleness.
Now, one thread goes to save. What operations get sent to the database ?
But imagine that impossible problem is solved. A database error
occurs, and we need to rollback. What changes get rolled back ?
Now, you're probably thinking, obviously, just that thread's changes
should get saved or undone. But at a semantic level, what does that
mean ? With bidirectional relationships, delete propagation, and
validation, is it even possible to make discrete changes ? What does
it mean for one thread to fetch an object with X amount of staleness
and another thread to fetch an object that has a relationship to the
first with Y amount of staleness ?
Is the object graph in a consistent state ? Can I correctly compute,
say a loan payment, if I fetched the interest rate at a different
time than I fetched the loan value and ancillary information ? How
would you even audit such a system if the objects' freshness differs
from the time the computation occurred ? Will you log every object's
staleness individually so you can explain to the lawyers how you
managed to get to the resultant loan payment ? People get kinda
funny when they don't get all the money owed to them.
The short answer is that you cannot touch anything in an EC without
semantically touching everything. Like throwing a pebble into a
pond, every operation ripples out. And just looking is dangerous
too. Ask Heisenberg or a girlfriend.
Locking is as much about transactional integrity as it is about
thread safety. It tells WebObjects "this resource is in use by this
thread" and the framework responds appropriately.
That's why awake() and sleep() are better choices for locking. The
scope is clearly defined and easily understood.
--
-Ben
_______________________________________________
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