Re: Selective commit

From: Andrus Adamchik (andru..bjectstyle.org)
Date: Tue Jan 08 2008 - 12:54:31 EST

  • Next message: marco turchi: "Commit Exception Error"

    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