Re: Selective commit

From: Andrus Adamchik (andru..bjectstyle.org)
Date: Tue Jan 08 2008 - 10:39:56 EST

  • Next message: Andrus Adamchik: "Re: Selective commit"

    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 - 10:40:34 EST