BTW, while I am investigating the bug with nested contexts ... do you
have to use them at all? Can you just use multiple peer DataContexts
instead?
Andrus
On Jan 8, 2008, at 5:39 PM, Andrus Adamchik wrote:
> Ok, let me look into it.
>
> Andrus
>
> On Jan 8, 2008, at 5:16 PM, Álvaro Martínez wrote:
>
>> I get the same deadlock with 3.0M2 :-(
>>
>>
>>
>> Name: Timer-4
>> State: BLOCKED on org.apache.cayenne.access.ObjectStor..9f698
>> owned by: Timer-0
>> Total blocked: 13 Total waited: 778
>>
>> Stack trace:
>> org
>> .apache
>> .cayenne
>> .access
>> .DataContextMergeHandler.graphChanged(DataContextMergeHandler.java:
>> 99)
>> sun.reflect.GeneratedMethodAccessor108.invoke(Unknown Source)
>> sun
>> .reflect
>> .DelegatingMethodAccessorImpl
>> .invoke(DelegatingMethodAccessorImpl.java:25)
>> java.lang.reflect.Method.invoke(Method.java:597)
>> org.apache.cayenne.util.Invocation.fire(Invocation.java:204)
>> org.apache.cayenne.event.EventManager
>> $Dispatch.fire(EventManager.java:397)
>> org
>> .apache
>> .cayenne.event.DispatchQueue.dispatchEvent(DispatchQueue.java:162)
>> org
>> .apache
>> .cayenne.event.DispatchQueue.dispatchEvent(DispatchQueue.java:58)
>> - locked org.apache.cayenne.event.DispatchQueu..5c80d8
>> org
>> .apache.cayenne.event.EventManager.dispatchEvent(EventManager.java:
>> 336)
>> org.apache.cayenne.event.EventManager.postEvent(EventManager.java:
>> 307)
>> org
>> .apache
>> .cayenne.access.DataContext.fireDataChannelChanged(DataContext.java:
>> 1704)
>> org
>> .apache.cayenne.access.DataContext.onContextFlush(DataContext.java:
>> 1189)
>> org.apache.cayenne.access.DataContext.onSync(DataContext.java:1167)
>> org
>> .apache.cayenne.access.DataContext.flushToParent(DataContext.java:
>> 1234)
>> - locked org.apache.cayenne.access.ObjectStor..92a34
>> org
>> .apache.cayenne.access.DataContext.commitChanges(DataContext.java:
>> 1138)
>> com
>> .ptb
>> .commons.db.services.StatsServices.addForClient(StatsServices.java:
>> 42)
>> com
>> .ptb
>> .backendnode
>> .tasks.DataMgrStatsCalculation.run(DataMgrStatsCalculation.java:78)
>> java.util.TimerThread.mainLoop(Timer.java:512)
>> java.util.TimerThread.run(Timer.java:462)
>>
>>
>>
>>
>> Name: Timer-0
>> State: BLOCKED on org.apache.cayenne.event.DispatchQueu..5c80d8
>> owned by: Timer-4
>> Total blocked: 5 Total waited: 22
>>
>> Stack trace:
>> org
>> .apache
>> .cayenne.event.DispatchQueue.dispatchEvent(DispatchQueue.java:54)
>> org
>> .apache.cayenne.event.EventManager.dispatchEvent(EventManager.java:
>> 336)
>> org.apache.cayenne.event.EventManager.postEvent(EventManager.java:
>> 307)
>> org
>> .apache
>> .cayenne.access.DataContext.fireDataChannelChanged(DataContext.java:
>> 1704)
>> org
>> .apache.cayenne.access.DataContext.onContextFlush(DataContext.java:
>> 1189)
>> org.apache.cayenne.access.DataContext.onSync(DataContext.java:1167)
>> org
>> .apache.cayenne.access.DataContext.flushToParent(DataContext.java:
>> 1234)
>> - locked org.apache.cayenne.access.ObjectStor..9f698
>> org
>> .apache.cayenne.access.DataContext.commitChanges(DataContext.java:
>> 1138)
>> com.ptb.confignode.ConfigNode.newConfigGenerated(ConfigNode.java:711)
>> - locked java.lang.Boolea..f6d5a
>> com
>> .ptb
>> .confignode
>> .tasks.GenerateNewDistribution.run(GenerateNewDistribution.java:162)
>> java.util.TimerThread.mainLoop(Timer.java:512)
>> java.util.TimerThread.run(Timer.java:462)
>>
>>
>>
>> Andrus Adamchik escribió:
>>>
>>> Could you also try it with 3.0M2? I wonder if there is a
>>> difference, before I start looking into that.
>>>
>>> Thanks
>>> Andrus
>>>
>>>
>>>
>>> On Jan 8, 2008, at 4:11 PM, Álvaro Martínez wrote:
>>>>
>>>> Of course, sorry, 2.0.4
>>>>
>>>>
>>>>
>>>> Andrus Adamchik escribió:
>>>>> Could you confirm the exact version of Cayenne you are using?
>>>>>
>>>>> Thanks,
>>>>> Andrus
>>>>>
>>>>> On Jan 8, 2008, at 4:05 PM, Álvaro Martínez wrote:
>>>>>
>>>>>>
>>>>>> Hi, I'm running some issues on this one.
>>>>>>
>>>>>> I now create a new child data context on every situation. But
>>>>>> I'm always getting the same deadlock. I can't figure out how to
>>>>>> fix this from my own code.
>>>>>>
>>>>>> I've googled other people who also had a similar problem, but
>>>>>> didn't help.
>>>>>>
>>>>>> This is the explanation from jConsole:
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> Name: Timer-0
>>>>>> State: BLOCKED on org.apache.cayenne.event.DispatchQueu..25268
>>>>>> owned by: Timer-4
>>>>>> Total blocked: 3 Total waited: 68
>>>>>>
>>>>>> Stack trace:
>>>>>> org
>>>>>> .apache
>>>>>> .cayenne.event.DispatchQueue.dispatchEvent(DispatchQueue.java:54)
>>>>>> org
>>>>>> .apache
>>>>>> .cayenne.event.EventManager.dispatchEvent(EventManager.java:336)
>>>>>> org
>>>>>> .apache.cayenne.event.EventManager.postEvent(EventManager.java:
>>>>>> 307)
>>>>>> org
>>>>>> .apache
>>>>>> .cayenne
>>>>>> .access.DataContext.fireDataChannelChanged(DataContext.java:1704)
>>>>>> org
>>>>>> .apache
>>>>>> .cayenne
>>>>>> .access
>>>>>> .DataContextMergeHandler
>>>>>> .graphFlushed(DataContextMergeHandler.java:114)
>>>>>> sun.reflect.GeneratedMethodAccessor65.invoke(Unknown Source)
>>>>>> sun
>>>>>> .reflect
>>>>>> .DelegatingMethodAccessorImpl
>>>>>> .invoke(DelegatingMethodAccessorImpl.java:25)
>>>>>> java.lang.reflect.Method.invoke(Method.java:597)
>>>>>> org.apache.cayenne.util.Invocation.fire(Invocation.java:204)
>>>>>> org.apache.cayenne.event.EventManager
>>>>>> $Dispatch.fire(EventManager.java:397)
>>>>>> org
>>>>>> .apache
>>>>>> .cayenne.event.DispatchQueue.dispatchEvent(DispatchQueue.java:
>>>>>> 162)
>>>>>> org
>>>>>> .apache
>>>>>> .cayenne.event.DispatchQueue.dispatchEvent(DispatchQueue.java:58)
>>>>>> - locked org.apache.cayenne.event.DispatchQueu..2d553e
>>>>>> org
>>>>>> .apache
>>>>>> .cayenne.event.EventManager.dispatchEvent(EventManager.java:336)
>>>>>> org
>>>>>> .apache.cayenne.event.EventManager.postEvent(EventManager.java:
>>>>>> 307)
>>>>>> org
>>>>>> .apache
>>>>>> .cayenne
>>>>>> .access.DataContext.fireDataChannelCommitted(DataContext.java:
>>>>>> 1680)
>>>>>> org
>>>>>> .apache
>>>>>> .cayenne.access.DataContext.flushToParent(DataContext.java:1247)
>>>>>> - locked org.apache.cayenne.access.ObjectStor..37958b
>>>>>> org
>>>>>> .apache
>>>>>> .cayenne.access.DataContext.onContextFlush(DataContext.java:1192)
>>>>>> org.apache.cayenne.access.DataContext.onSync(DataContext.java:
>>>>>> 1167)
>>>>>> org
>>>>>> .apache
>>>>>> .cayenne.access.DataContext.flushToParent(DataContext.java:1234)
>>>>>> - locked org.apache.cayenne.access.ObjectStor..b3a10d
>>>>>> org
>>>>>> .apache
>>>>>> .cayenne.access.DataContext.commitChanges(DataContext.java:1138)
>>>>>> com
>>>>>> .ptb.confignode.ConfigNode.newConfigGenerated(ConfigNode.java:
>>>>>> 711)
>>>>>> - locked java.lang.Boolea..b13c5
>>>>>> com
>>>>>> .ptb
>>>>>> .confignode
>>>>>> .tasks.GenerateNewDistribution.run(GenerateNewDistribution.java:
>>>>>> 162)
>>>>>> java.util.TimerThread.mainLoop(Timer.java:512)
>>>>>> java.util.TimerThread.run(Timer.java:462)
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> Name: Timer-4
>>>>>> State: BLOCKED on org.apache.cayenne.access.ObjectStor..b3a10d
>>>>>> owned by: Timer-0
>>>>>> Total blocked: 20 Total waited: 799
>>>>>>
>>>>>> Stack trace:
>>>>>> org
>>>>>> .apache
>>>>>> .cayenne
>>>>>> .access
>>>>>> .DataContextMergeHandler
>>>>>> .graphChanged(DataContextMergeHandler.java:99)
>>>>>> sun.reflect.GeneratedMethodAccessor69.invoke(Unknown Source)
>>>>>> sun
>>>>>> .reflect
>>>>>> .DelegatingMethodAccessorImpl
>>>>>> .invoke(DelegatingMethodAccessorImpl.java:25)
>>>>>> java.lang.reflect.Method.invoke(Method.java:597)
>>>>>> org.apache.cayenne.util.Invocation.fire(Invocation.java:204)
>>>>>> org.apache.cayenne.event.EventManager
>>>>>> $Dispatch.fire(EventManager.java:397)
>>>>>> org
>>>>>> .apache
>>>>>> .cayenne.event.DispatchQueue.dispatchEvent(DispatchQueue.java:
>>>>>> 162)
>>>>>> org
>>>>>> .apache
>>>>>> .cayenne.event.DispatchQueue.dispatchEvent(DispatchQueue.java:58)
>>>>>> - locked org.apache.cayenne.event.DispatchQueu..25268
>>>>>> org
>>>>>> .apache
>>>>>> .cayenne.event.EventManager.dispatchEvent(EventManager.java:336)
>>>>>> org
>>>>>> .apache.cayenne.event.EventManager.postEvent(EventManager.java:
>>>>>> 307)
>>>>>> org
>>>>>> .apache
>>>>>> .cayenne
>>>>>> .access.DataContext.fireDataChannelChanged(DataContext.java:1704)
>>>>>> org
>>>>>> .apache
>>>>>> .cayenne.access.DataContext.onContextFlush(DataContext.java:1189)
>>>>>> org.apache.cayenne.access.DataContext.onSync(DataContext.java:
>>>>>> 1167)
>>>>>> org
>>>>>> .apache
>>>>>> .cayenne.access.DataContext.flushToParent(DataContext.java:1234)
>>>>>> - locked org.apache.cayenne.access.ObjectStor..86d2f
>>>>>> org
>>>>>> .apache
>>>>>> .cayenne.access.DataContext.commitChanges(DataContext.java:1138)
>>>>>> com
>>>>>> .ptb
>>>>>> .commons
>>>>>> .db.services.StatsServices.addForClient(StatsServices.java:42)
>>>>>> com
>>>>>> .ptb
>>>>>> .backendnode
>>>>>> .tasks.DataMgrStatsCalculation.run(DataMgrStatsCalculation.java:
>>>>>> 78)
>>>>>> java.util.TimerThread.mainLoop(Timer.java:512)
>>>>>> java.util.TimerThread.run(Timer.java:462)
>>>>>>
>>>>>>
>>>>>>
>>>>>> Thanks!
>>>>>>
>>>>>>
>>>>>> Michael Gentry escribió:
>>>>>>>
>>>>>>> Hi Álvaro,
>>>>>>>
>>>>>>> Creating a DataContext is a fairly cheap operation. I would
>>>>>>> suggest
>>>>>>> creating them as you need them and not try to optimize this
>>>>>>> operation
>>>>>>> at this point. If you run into bottlenecks in the future,
>>>>>>> then maybe
>>>>>>> look at other options, but there is a good chance that
>>>>>>> creating extra
>>>>>>> DataContexts will not be the source of a performance problem.
>>>>>>>
>>>>>>> /dev/mrg
>>>>>>>
>>>>>>>
>>>>>>> On Jan 7, 2008 10:30 AM, Álvaro Martínez <alvaro_martine..tbsl.com
>>>>>>> > wrote:
>>>>>>>
>>>>>>>> Thanks, Andrus and Philip
>>>>>>>>
>>>>>>>> The threads I'm talking about are created from many sources
>>>>>>>> and for
>>>>>>>> different reasons. Not of all them are triggered in response to
>>>>>>>> "something". There are also watchers, periodic tasks... So I
>>>>>>>> can't map
>>>>>>>> data contexts to some particular condition.
>>>>>>>>
>>>>>>>> So then I have to create one data context per operation (that
>>>>>>>> means a
>>>>>>>> set of actions). Is this expensive? We are developing a heavy
>>>>>>>> loaded
>>>>>>>> cluster of servers, so it's important.
>>>>>>>>
>>>>>>>> Thanks again!
>>>>>>>>
>>>>>>>>
>>>>>>>> Andrus Adamchik escribió:
>>>>>>>>
>>>>>>>>
>>>>>>>>> Hi Álvaro,
>>>>>>>>>
>>>>>>>>> It is hard to give a precise advice on multithreading
>>>>>>>>> without knowing
>>>>>>>>> the nature of your application. So here is a few general
>>>>>>>>> notes:
>>>>>>>>>
>>>>>>>>> * DataContext instance is your isolated area for making in-
>>>>>>>>> memory
>>>>>>>>> changes to objects that will all be committed at once. So
>>>>>>>>> consider
>>>>>>>>> using multiple contexts as appropriate. Cayenne docs
>>>>>>>>> recommend various
>>>>>>>>> common patterns, such as DataContext per session (i.e. each
>>>>>>>>> user has a
>>>>>>>>> dedicated context), DataContext per request, or DataContext
>>>>>>>>> per
>>>>>>>>> application (in a read-only app). You can also devise your own
>>>>>>>>> approach, if none of the above fit your needs. All you need
>>>>>>>>> to know
>>>>>>>>> here is that multiple threads *reading* from a shared
>>>>>>>>> DataContext is
>>>>>>>>> ok, but multiple threads *writing* to a shared DataContext
>>>>>>>>> is not ok.
>>>>>>>>>
>>>>>>>>> * In a rare case if you really need multiple threads to work
>>>>>>>>> off of
>>>>>>>>> the same context, consider using a dedicated nested
>>>>>>>>> DataContext for
>>>>>>>>> each atomic object modifications.
>>>>>>>>>
>>>>>>>>> Andrus
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Jan 7, 2008, at 2:44 PM, Álvaro Martínez wrote:
>>>>>>>>>
>>>>>>>>>> Hi, I've been working for a while with Cayenne but never
>>>>>>>>>> realized I
>>>>>>>>>> had a problem... until I got a weird exception.
>>>>>>>>>>
>>>>>>>>>> The fact is that I had been using context.newObject() and
>>>>>>>>>> context.commitChanges() to create new rows in the database.
>>>>>>>>>> But my
>>>>>>>>>> application works with many threads, so global commits can
>>>>>>>>>> (and in
>>>>>>>>>> fact do) interrupt normal creation of objects. Thread A and
>>>>>>>>>> Thread B
>>>>>>>>>> are creating objects and filling their fields, but then B
>>>>>>>>>> commits all
>>>>>>>>>> and A throws a validation exception because mandatory
>>>>>>>>>> fields are
>>>>>>>>>> missing.
>>>>>>>>>>
>>>>>>>>>> How could I commit only one object?
>>>>>>>>>>
>>>>>>>>>> Thanks,
>>>>>>>>>>
>>>>>>>>>> Álvaro from Spain (Push the button Inc.)
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>>
>>>
>>
>
>
This archive was generated by hypermail 2.0.0 : Tue Jan 08 2008 - 12:55:21 EST