Hmm... I'm using background threads in my apps to do some processing. The
thread creates is editing context for its own use. Something like this:
EOObjectStoreCoordinator parentObjectStore = new
EOObjectStoreCoordinator();
editingContext = ERXEC.newEditingContext(parentObjectStore);
I pass GIDs to this background thread. But if I understand what you are
saying, creating the editing context like this can still get me in trouble
still.
Ricardo
On Feb 17, 2010, at 3:23 PM, Kieran Kelleher wrote:
> 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 ([email protected])
>> Help/Unsubscribe/Update your Subscription:
>> http://lists.apple.com/mailman/options/webobjects-dev/kieran_lists%40mac.com
>>
>> This email sent to [email protected]
>
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Webobjects-dev mailing list ([email protected])
> Help/Unsubscribe/Update your Subscription:
> http://lists.apple.com/mailman/options/webobjects-dev/rparada%40mac.com
>
> This email sent to [email protected]
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com
This email sent to [email protected]