Philippe,

This isn't the same thing. Between the line that creates and the line that sets 
autolock to false below, another thread could call a method that triggers an 
autolock.

If you can find the old discussion on this, you will see that I was actually 
doing sth like you have shown here and I still got deadlocks. Anjo's smart 
suggestion to return the anonymous inline subclass (if that's the right 
terminology) was the correct way to *guarantee* that the autolocking was off 
during instantiation of the EC.

Really, just paste the few lines of code I gave u yesterday into a file and 
name it MyEOUtils.java, and then change your code below to use the static 
factory method to create the 'manual locking' ec.

Regards, Kieran


On Feb 18, 2010, at 5:30 AM, Philippe Rabier wrote:

> Thanks Kieran, Ricardo, Anjo, Jon.
> 
> Kieran, I follow your lead actually.
> 
> I don't have too many threads/classes (just 3 classes) so I just modified my 
> editingContext() in the classes like that:
> 
>       protected EOEditingContext editingContext()
>       {
>               if (editingContext  == null)
>               {
>                       editingContext = ERXEC.newEditingContext();
>                       ((ERXEC) editingContext).setUseAutoLock(false);
>               }
>               return editingContext;
>       }
> 
> I thought about passing globalIDs but my description is a little bit simpler 
> than my code so I can't (without changing the design).
> 
> Have a good day.
> 
> Philippe
> 
> On 17 févr. 2010, at 21:23, 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      (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/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