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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.