Some tidbits that might help:

1) Don't pass EOs between threads. Pass their EOGlobalIDs and use 
ec.faultForGlobalID to rehydrate them in an ec in the thread that needs them.  
Use Wonder ERXEO<Something>Utilities.convertEOtoGID if desired.  (Something  = 
'Access' or 'Control', I can never remember which)

2) If you have autolocking on and if you are using ERXEC.newEditingContext, you 
may get deadlocks. To continue to use autolocking in request threads and to 
created guaranteed non-autolocking EC's in plain old background threads, you 
can paste this into your own EO Utils class and just use the static creation 
method:


        /**
         * Anonymous ERXEC factory that creates manual locking ec's in an app 
where safeLocking is on by default
         */
        private static ERXEC.Factory manualLockingEditingContextFactory = new 
ERXEC.DefaultFactory() {

                @Override
                protected EOEditingContext _createEditingContext(EOObjectStore 
parent) {
                        return new ERXEC(parent == null ? 
EOEditingContext.defaultParentObjectStore() : parent) {
                                @Override
                                public boolean useAutoLock() {return false;}

                                @Override
                                public boolean coalesceAutoLocks() {return 
false;}
                        };
                }
        };

        /**
         * @return a regular ERXEC with no auto-locking features
         */
        public static EOEditingContext newManualLockingEditingContext() {
                return manualLockingEditingContextFactory._newEditingContext();
        }
        
        /**
         * I do not want autolocking in non-request threads
         * 
         * @param parent
         * @return an ERXEC with safeLocking properties turned OFF.
         */
        public static EOEditingContext 
newManualLockingEditingContext(EOObjectStore parent) {
                return 
manualLockingEditingContextFactory._newEditingContext(parent);
        }



3) Depending on the intensity of the EOF activity, you may want to use a 
different EOObjectStoreCoordinator than the default or a pool of them for 
background threads so as not to interfere with request thread EOF performance.









On Feb 17, 2010, at 2:34 PM, Philippe Rabier wrote:

> Hi all,
> 
> I get an issue with a multi threaded application. To be easier to understand, 
> my description is simpler than the reality but that's enough to see what's 
> going on I guess.
> 
> I'm using:
> WO 5.4.3
> Snow Leopard/ java 6
> Wonder (not the very last but not old)
> I put the following properties:
> er.extensions.ERXEC.traceOpenLocks=true
> er.extensions.ERXEC.markOpenLocks=true
> 
> There 2 threads (not worker threads handled by WO) created by a 
> frameworkPrincipal (in the wonder sense) with a classical run loop (while 
> (true)....).
> 
> BigObject A running in thread A has an editingContext A (ecA) that fetches, 
> for example, customers from entity Customer
> 
> BigObject B running in thread B has an editingContext B (ecB) that fetches 
> objects, for example invoices from entity Invoice. Invoice has a to one 
> relationship with Customer
> 
> BigObject A passes to BigObject B a list of customers. Suppose there is only 
> one customer in the list.
> 
> Object B periodically fetches invoices, customer by customer, so it 
> constructs a qualifier like invoice.customer.eq(aCustomer), then a fetchspec, 
> ... Of course, there is some code like:
> 
> ecB.lock();
> try
>       invoices = ecB.objectsWithFetchSpecification(fetchSpecification);
> catch
> finally
> ecB.unlock();
> 
> The log tells me that when ecB.objectsWithFetchSpecification is executed, ecA 
> is locked. And it's locked forever. I wasn't sure to have to use a 
> localInstance of customer because I use it only to create a qualifier. But I 
> did the test and it's worth.
> 
> If I execute something like that before the construction of the qualifier:
>  myCustomers = EOUtilities.localInstanceOfObject(ecB, customers);
> 
> ecA and ecB are locked automatically and never unlocked.
> 
> I found a solution, that's to lock/unlock both editingContexts but I'm 
> unsatisfied because I don't understand why EOUtilities.localInstance locks 
> ecA and ecB and doesn't unlock them. Naturally I would find the good way to 
> use it.
> 
> Any idea what's going on? 
> 
> The stack trace when ecA is locked by BigObjectB:
> 
> Outstanding at @Thread[Thread-4,5,main]
> java.lang.Exception: Locked
>       at er.extensions.eof.ERXEC.traceLock(ERXEC.java:532)
>       at er.extensions.eof.ERXEC.lock(ERXEC.java:502)
>       at er.extensions.eof.ERXEC.autoLock(ERXEC.java:627)
>       at er.extensions.eof.ERXEC.globalIDForObject(ERXEC.java:844)
>       at 
> com.webobjects.eoaccess.EODatabaseContext._globalIDForObject(EODatabaseContext.java:4644)
>       at 
> com.webobjects.eoaccess.EODatabaseContext.databaseOperationForObject(EODatabaseContext.java:4767)
>       at 
> com.webobjects.eoaccess.EODatabaseContext.valuesForKeys(EODatabaseContext.java:6535)
>       at 
> com.webobjects.eocontrol.EOObjectStoreCoordinator.valuesForKeys(EOObjectStoreCoordinator.java:326)
>       at 
> com.webobjects.eoaccess.EOQualifierSQLGeneration$_KeyValueQualifierSupport.schemaBasedQualifierWithRootEntity(EOQualifierSQLGeneration.java:439)
>       at 
> er.extensions.ERXExtensions$KeyValueQualifierSQLGenerationSupport.schemaBasedQualifierWithRootEntity(ERXExtensions.java:333)
>       at 
> com.webobjects.eoaccess.EOQualifierSQLGeneration$Support._schemaBasedQualifierWithRootEntity(EOQualifierSQLGeneration.java:179)
>       at 
> com.webobjects.eoaccess.EOQualifierSQLGeneration$_AndQualifierSupport.schemaBasedQualifierWithRootEntity(EOQualifierSQLGeneration.java:530)
>       at 
> com.webobjects.eoaccess.EOQualifierSQLGeneration$Support._schemaBasedQualifierWithRootEntity(EOQualifierSQLGeneration.java:179)
>       at 
> com.webobjects.eoaccess.EODatabaseChannel.selectObjectsWithFetchSpecification(EODatabaseChannel.java:227)
>       at 
> com.webobjects.eoaccess.EODatabaseContext._objectsWithFetchSpecificationEditingContext(EODatabaseContext.java:3055)
>       at 
> com.webobjects.eoaccess.EODatabaseContext.objectsWithFetchSpecification(EODatabaseContext.java:3195)
>       at 
> com.webobjects.eocontrol.EOObjectStoreCoordinator.objectsWithFetchSpecification(EOObjectStoreCoordinator.java:488)
>       at 
> com.webobjects.eocontrol.EOEditingContext.objectsWithFetchSpecification(EOEditingContext.java:4069)
>       at 
> er.extensions.eof.ERXEC.objectsWithFetchSpecification(ERXEC.java:1211)
>       at 
> com.webobjects.eocontrol.EOEditingContext.objectsWithFetchSpecification(EOEditingContext.java:4444)
>       at fr.sophiacom.ynp.push.BigObjectB.fetchesInvoice(BigObjectB.java:238)
>       at fr.sophiacom.BigObjectB._run(BigObjectB.java:110)
>       at er.extensions.concurrency.ERXRunnable.run(ERXRunnable.java:23)
>       at java.lang.Thread.run(Thread.java:637)
> 
> Philippe
> 
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Webobjects-dev mailing list      (Webobjects-dev@lists.apple.com)
> Help/Unsubscribe/Update your Subscription:
> http://lists.apple.com/mailman/options/webobjects-dev/kieran_lists%40mac.com
> 
> This email sent to kieran_li...@mac.com

 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      (Webobjects-dev@lists.apple.com)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to