Re: currently saving for so it cannot prepare to save for
"Jerry W. Walker" <[email protected]>
| Newsgroups | gmane.comp.web.webobjects.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi, Chad,
On Jan 19, 2006, at 11:18 AM, Chad Pilkington wrote:
> Thankyou for the help. Please feel free to correct my
> understanding or point me to some documentation where it would be
> located.
I suppose the best all around documentation for these issues is the
Hill/Mailais _Practical_WebObjects_ book.
For immediately available general information on the topic, you might
also read through EOEditingContext Conceps page of the distributed
documentation found on your WO development machine at:
file:///Developer/Documentation/WebObjects/Reference/API/com/
webobjects/eocontrol/concepts/EOEditingContextConcepts.html
I would also suggest the WO EOF Commandments at:
http://wodev.spearway.com/cgi-bin/WebObjects/WODev.woa/wa/Main?
wikiPage=EOFCommandments
> It is my understading that Child editing contexts do not actually
> save anything. When you issue a saveChanges() on a Child editing
> context it posts the changed information back up to the parent
> editing context which then in turn must be saved to make the
> changes occur in the database. Also if I create a sibling editing
> context how is this different then two users being in the system
> and having their own session editing contexts.
You are correct that child editing contexts do not actually save
anything to the database, but rather save the EO to the parent
editing context which serves the child as the EOObjectStore (of which
the editing context is a subclass). However, editing contexts are
involved in a lot of activity with regard to the EOs independent of
its being saved to the database. In order to make this activity
thread safe, the editing context must be locked.
If you're using the Session's default editing context, it also must
be locked before use, but the Session does the locking for you so you
don't have to worry about it. I've heard it said that child editing
contexts are locked by their parent. This is not true. It is true
that they share the same lock object, but locking the parent does not
lock the child.
To quote Chuck and Sacha's book, _Practical_WebObjects_ on page 84 it
says:
Locking the parent editing context does nothing to lock the
children. The
shared lock object simply prevents different threads from
locking the parent
and child or from locking two different children of the same
parent.
However, locking the child editing context does indeed lock the
parent!
For any editing context that you create programmatically, you must
manage its locking to be safe (that is, lock it before use and unlock
it after use).
The only major difference between your creating a sibling editing
context and "... two users being in the system and having their own
session editing contexts" is that in the former case, you created the
editing contexts and, therefore, must manage their locking. In the
latter case, I'm presuming that the two users are each using the
default editing context provided by their respective WOSession. If
so, those editing contexts are automatically locked appropriately for
each user.
Regarding editing context locking in general, the documentation page,
EOEditingContextConcepts, sited above contains the following sentence:
You are responsible for ensuring thread safe handling of any
EOEditingContexts
you create programmatically by using the lock and unlock methods.
> Also, the method you quoted (EOObjectStoreCoordinator.lock()) talks
> about "concurrent operations by multiple threads". As I understand
> it if you have only one instance of the application as it is
> normally set up you do not have multiple threads so there should
> never be concurrent operations.
This is incorrect in two ways. First, the number of INSTANCES of
your application will have little to no effect on the threading in a
given instance. The instances will be vying with each other through
multiprocessing, but threads cannot (by definition) be crossing the
instance boundary, because each instance is contained within its own
process.
Second, EVERY WO application today is a multithreaded application. By
and large, unless you set up multi-threaded adaptors to dispatch
requests concurrently, you are pretty well guaranteed that there will
be a SINGLE Request-Response thread. But WO doesn't wait around for
your R-R thread in order to pursue it's low level EO stack work or
its adaptor work. It's the lower level EO stack work that can
conflict with your R-R thread's access to the
EOObjectStoreCoordinator and the objects with which it works.
> If I lock the EOObjectStoreCoordinator and another request is made
> of the object Store Coordinator what will happen? Will I get an
> error or will the other Request wait until the Coordinator is
> unlocked?
Presuming no deadlocks, the latter.
> Do you know of any information on eactly what communication path
> to the database rawRowsForSql is using?
Offhand, no, I don't. Perhaps others on the list could respond to this.
You could probably piece it together by starting with the
EODatabaseContext documentation. The actual SQL for a standard fetch
is put together by the EOAdaptorChannel, so I presume that
EOUtilities is feeding the SQL directly to the EOAdaptorChannel
through the latter's evaluateExpression() method which isn't used by
the higher levels of the EO stack. Perhaps it would help to know the
normal data path down through the EO stack.
The path is a bit complex but the direct path generally includes the
EOEditingContext, the EOObjectStoreCoordinator, the EODatabaseContext
(which manages the EODatabaseChannels and the EODatabase) and the
EOAdaptorContext (which manages the EOAdaptorChannels and the
EOAdaptor).
With those names at hand, you should be able to find your way through
the documentation.
HTH.
Regards,
Jerry
> ----- Original Message -----
> From: Jerry W. Walker
> To: Chad Pilkington
> Cc: [email protected]
> Sent: Thursday, January 19, 2006 8:53 AM
> Subject: Re: currently saving for so it cannot prepare to save for
>
> Hi, Chad,
>
> This looks like a failure to lock the EOObjectStoreCoordinator.
> Typically, this is done by default in the standard use of the
> default editing context. The following is from the
> EOObjectStoreCoordinator JavaDoc documentation for the lock method:
>
> ========================
> This method is used to protect access to the receiver from
> concurrent operations by multiple threads. EOEditingContexts will
> indirectly lock their EOObjectStoreCoordinators when necessary.
> Locking an EOObjectStoreCoordinator will cause the coordinator to
> lock each registered EOCooperatingObjectStore managed by that
> coordinator. Applications which make direct use of an
> EOObjectStoreCoordinator should lock and unlock it as appropriate.
> Do not confuse this with any methods which work with the database
> locking mechanism.
> ========================
>
> If you reformat your error message as follows it looks more like a
> stack trace:
>
> ========================
> IllegalStateException: prepareForSaveWithCoordinator:
> EODatabaseContext@e9e799 is currently saving for
> EOEditingContext@aa0933 so it cannot prepare to save for
> EOEditingContext@c73be3.
>
> EOObjectStoreCoordinator@3d2b3 has sources (EODatabaseContext@e9e799)
> at EODatabaseContext.prepareForSaveWithCoordinator
> (EODatabaseContext.java:5763)
> at EOObjectStoreCoordinator.saveChangesInEditingContext
> (EOObjectStoreCoordinator.java:405)
> at EOEditingContext.saveChanges(EOEditingContext.java:3128)
> at Main.actLoginAdmin(Main.java:328)
> at sun.reflect.GeneratedMethodAccessor174.invoke(Unknown Source)
> at sun.reflect.DelegatingMethodAccessorImpl.invoke
> (DelegatingMethodAccessorImpl.java:25)
> at reflect.Method.invoke(Method.java:324)
> at KeyValueCodingProtectedAccessor.methodValue
> (KeyValueCodingProtectedAccessor.java:54)
> at NSKeyValueCoding$_MethodBinding.valueInObject
> (NSKeyValueCoding.java:1160)
> at NSKeyValueCoding$DefaultImplementation.valueForKey
> (NSKeyValueCoding.java:1268)
> at WOComponent.valueForKey(WOComponent.java:1544)
> ========================
>
> The error seems to be occurring at Main.actLoginAdmin(Main.java:
> 328). You might start with that statement to see if any code is
> directly accessing the EOObjectStoreCoordinator directly without
> locking.
>
> You also mentioned that you are only using the Session's default
> editing context and sometimes a child thereof. The child editing
> contexts should be explicitly locked. Check also to be sure that
> the code is not creating a peer editing context by leaving out the
> reference to the default editing context in the constructor message.
>
> HTH.
>
> Regards,
> Jerry
>
> On Jan 18, 2006, at 9:38 PM, Chad Pilkington wrote:
>
>> I have an applicaton where I am getting this error a lot:
>> java.lang.IllegalStateException: prepareForSaveWithCoordinator:
>> com.webobjects.eoaccess.EODatabaseContext@e9e799 is currently
>> saving for com.webobjects.eocontrol.EOEditingContext@aa0933 so it
>> cannot prepare to save for
>> com.webobjects.eocontrol.EOEditingContext@c73be3.
>> com.webobjects.eocontrol.EOObjectStoreCoordinator@3d2b3 has
>> sources (com.webobjects.eoaccess.EODatabaseContext@e9e799) at
>> com.webobjects.eoaccess.EODatabaseContext.prepareForSaveWithCoordinat
>> or(EODatabaseContext.java:5763) at
>> com.webobjects.eocontrol.EOObjectStoreCoordinator.saveChangesInEditin
>> gContext(EOObjectStoreCoordinator.java:405) at
>> com.webobjects.eocontrol.EOEditingContext.saveChanges
>> (EOEditingContext.java:3128) at Main.actLoginAdmin(Main.java:328)
>> at sun.reflect.GeneratedMethodAccessor174.invoke(Unknown Source)
>> at sun.reflect.DelegatingMethodAccessorImpl.invoke
>> (DelegatingMethodAccessorImpl.java:25) at
>> java.lang.reflect.Method.invoke(Method.java:324) at
>> KeyValueCodingProtectedAccessor.methodValue
>> (KeyValueCodingProtectedAccessor.java:54) at
>> com.webobjects.foundation.NSKeyValueCoding
>> $_MethodBinding.valueInObject(NSKeyValueCoding.java:1160) at
>> com.webobjects.foundation.NSKeyValueCoding
>> $DefaultImplementation.valueForKey(NSKeyValueCoding.java:1268) at
>> com.webobjects.appserver.WOComponent.valueForKey(WOComponent.java:
>> 1544)
>>
>> I am having difficulty discovering exactly how this particuar
>> error is possible using only one EOModel and one Instance of an
>> application. I have never seen this error before in any of my
>> other applications. The only real difference that I can see is
>> that this application has a mySql v 4.0.18 backend where our other
>> applications have OpenBase backend. As far as I can tell this
>> error is occuring at a far higher level then the actual database
>> level. The application is running on OSX 10.2.8 via monitor. It
>> was built in WebObjects 5.2 and is using the
>> org.gjt.mm.mysql.Driver v 3.0.8. The application is not using any
>> special Editing Contexts. just the session().defaultEditingContext
>> () and the occational child of that contect new EOEditngContext
>> (session().defaultEditingContext()). Does anyone have any idea
>> what the problem is?
>> _______________________________________________
>> WebObjects-dev mailing list
>> [email protected]
>> http://www.omnigroup.com/mailman/listinfo/webobjects-dev
>
>
> --
> __ Jerry W. Walker,
> WebObjects Developer/Instructor for High Performance Industrial
> Strength Internet Enabled Systems
>
> [email protected]
> 203 278-4085 office
>
>
>
>
>
> _______________________________________________
> WebObjects-dev mailing list
> [email protected]
> http://www.omnigroup.com/mailman/listinfo/webobjects-dev
>
--
__ Jerry W. Walker,
WebObjects Developer/Instructor for High Performance Industrial
Strength Internet Enabled Systems
[email protected]
203 278-4085 office
_______________________________________________
WebObjects-dev mailing list
[email protected]
http://www.omnigroup.com/mailman/listinfo/webobjects-dev