Re: Autolocking Editing Contexts outside of normal WO Request Response Loops??
Re: Autolocking Editing Contexts outside of normal WO Request Response Loops??
- Subject: Re: Autolocking Editing Contexts outside of normal WO Request Response Loops??
- From: Dov Rosenberg <email@hidden>
- Date: Sun, 26 Sep 2010 13:01:40 -0700
- Acceptlanguage: en-US
- Thread-topic: Autolocking Editing Contexts outside of normal WO Request Response Loops??
Here is the very simple method that is being called by an external process
without going thru a WO request/response loop. The method is a web service
call that is intended to be essentially stateless. Only publicly available
NON EOF classes are passed in and out as parameters. This method could be
called by several different threads of execution based on user interaction
in the UI.
public static CaseLinkITO deleteCaseLink(CaseLinkITO caseLink,
ContentRecordKeyITO contentRecordKey) {
boolean success = false;
UserInformation user = null;
Content content = null;
CaseLinkITO returncaseLink = caseLink;
int incidentVal = 0;
NSArray<CaseLinkContent> list = null;
EOEditingContext ec = ERXEC.newEditingContext();
ec.lock();
try {
...
ec.saveChanges();
success = true;
}
else {
...
}
} catch (Exception e) {
ec.revert();
}
finally {
ec.unlock();
}
...
return returncaseLink;
}
On 9/26/10 3:52 PM, "Kieran Kelleher" <email@hidden> wrote:
> Copy/paste the source for the method of concern here ...... maybe someone can
> see a problem......
>
> On Sep 26, 2010, at 2:42 PM, Dov Rosenberg wrote:
>
>> Thanks for the input. Here is what is perplexing me about ERXEC. From my
>> logs with DEBUG turned on I can see things like the following
>>
>> [http-8226-Processor20] DEBUG er.extensions.ERXEC.LockLogger - locked
>> er.extensions.eof.ERXEC@14d9f162
>>
>> [http-8226-Processor16] DEBUG er.extensions.ERXEC.LockLogger - locked
>> er.extensions.eof.ERXEC@14d9f162
>>
>> I notice that the same EC is being used within the same thread with
>> different method invocations (initiated by separate user clicks in the UI)
>> and in different threads performing different actions. All of our calls at
>> the beginning of the methods create a new EC (we thought) by doing:
>>
>> ERXEC.newEditingContext();
>>
>> I would assume that I would get a different hashcode for different ECs
>> unless I am somehow reusing the ECs.
>>
>> As I mentioned before - this particular app has autolocking turned on but
>> does not use the WO request/response loop.
>>
>> This is the constructor for ERXEC which is called out by
>> createEditingContext() - I am unsure what the activeEditingContexts
>> structure is doing.
>>
>> public ERXEC(EOObjectStore os) {
>> super(os);
>> super._initWithParentObjectStore(os);
>>
>> ERXEnterpriseObject.Observer.install();
>> if (ERXEC.markOpenLocks()) {
>> creationTrace = new Exception("Creation");
>> creationTrace.fillInStackTrace();
>> activeEditingContexts.put(this,
>> Thread.currentThread().getName());
>> }
>> }
>>
>> It appears in my log files that somehow the same editing context is being
>> used between different method calls which I think is causing our
>> locking/unlocking to get out of sync. The methods that are being called only
>> use a single EC that is created and locked at the top of the method and
>> unlocked in a FINALLY block at the end.
>>
>> Could the fact that this method is declared as a static method be causing
>> this strange behavior? Maybe that is not a very thread safe way of handling
>> this.
>>
>> Thanks again for your insights
>>
>> Dov Rosenberg
>>
>>
>>
>> On 9/26/10 1:29 PM, "Kieran Kelleher" <email@hidden> wrote:
>>
>>>
>>> On Sep 26, 2010, at 10:11 AM, Dov Rosenberg wrote:
>>>
>>>> We have a couple of WO/EOF based applications that use project wonder
>>>> deployed as servlets in Tomcat. One of the apps is a classic WO app that
>>>> uses
>>>> WO components and a standard WO request/response loop. Our other 2 apps
>>>> don¹t use WOComponents but do use EOF. Consequently the other 2 apps do not
>>>> use the regular WO request/response loop.
>>>>
>>>> I have a couple of questions:
>>>>
>>>>
>>>> 1. Looking into ERXEC it appears that when a new ERXEC is created it is
>>>> bound into the ThreadLocal variable. If that thread makes additional calls
>>>> to
>>>> newEditingContext() it appears to always return the same ERXEC is that
>>>> true/by design? It doesn¹t seem to get a new ERXEC.
>>>
>>> Not true according to ERXEC.DefaultFactory._createEditingContext(...)
>>>
>>> /**
>>> * Actual EC creation bottleneck. Override this to return other
>>> * subclasses.
>>> */
>>> protected EOEditingContext _createEditingContext(EOObjectStore parent) {
>>> return new ERXEC(parent == null ?
>>> EOEditingContext.defaultParentObjectStore()
>>> : parent);
>>> }
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>> 2. When using an ERXEC in a thread we typically do something like:
>>>>
>>>> ERXEC ec = ERXEC.newEditingContext();
>>>> ec.lock();
>>>> try {
>>>> ...
>>>> } finally {
>>>> ec.unlock();
>>>> }
>>>>
>>>> Should we call ec.dispose() when we are done with the ec we created
>>>> in
>>>> the scope of the method? Will that prevent the ec from being reused in
>>>> subsequent calls to the method by the same thread?
>>>
>>> you don't have to call ec.dispose(), but you can if you want. If you do, it
>>> is
>>> a useful practice to make ec = null; immediately after calling ec.dispose()
>>>
>>>
>>>
>>>
>>>
>>>>
>>>> 3. Will the built in autolocking/unlocking work correctly if the WO
>>>> request/response loop is not used? Should we disable the autolocking
>>>> functionality if we are not using the WO request/response loop? Are there
>>>> other settings that should be set if we do not use autolocking?
>>>
>>> Auto lock/unlock is turned on/off by properties. Auto lock/unlock works by
>>> virtue of the fact that touching an ERXEC that isn't locked will cause it to
>>> be locked and the unlocking is performed automatically at the end of the
>>> request by the method: ERXEC.unlockAllContextsForCurrentThread(), which is
>>> called at the end of a request by ERXApplication._endRequest()
>>>
>>>
>>>
>>>>
>>>> The reason I am asking these questions is that I am have some hanging
>>>> issues
>>>> in the apps that do not use the WO request/response functionality. Tracing
>>>> the ERXEC locking behavior I can see there are cases where there are an
>>>> UNEQUAL number of lock and unlock operations. Usually the hung threads have
>>>> an extra lock operation. I suspect that is the root cause of my hung
>>>> threads.
>>>> It seems that the reuse of editing contexts within a thread causes the
>>>> mismatch in the number of locks/unlocks.
>>>
>>> For apps that don't have any requests, you can just turn off autolocking.
>>> You
>>> can call ERXEC.unlockAllContextsForCurrentThread() yourself at the end of a
>>> background thread task as safety net for unbalanced locks, however it is
>>> advised to use the construct above ec.lock()/try/finally/ec.unlock() in
>>> background threads always.
>>>
>>> If you are familiar with java.util.concurrent, you can use
>>> ERXExecutorService.executorService() to submit Callables and Runnable for
>>> background execution and at the end of your task,
>>> ERXEC.unlockAllContextsForCurrentThread() is called for automatically.
>>>
>>> http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Execut
>>> or
>>> Service.html
>>>
>>> HTH, Kieran
>>>
>>>
>>>>
>>>> Thanks in advance for any insights you can provide
>>>>
>>>> Dov Rosenberg
>>>>
>>>> _______________________________________________
>>>> Do not post admin requests to the list. They will be ignored.
>>>> Webobjects-dev mailing list (email@hidden)
>>>> Help/Unsubscribe/Update your Subscription:
>>>>
>>>> This email sent to email@hidden
>>>
>>
>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden