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/archive%40mail-archive.com
This email sent to [email protected]