Re: Selective commit

From: Álvaro Martínez (alvaro_martine..tbsl.com)
Date: Wed Jan 09 2008 - 03:28:46 EST

  • Next message: Álvaro Martínez: "Re: Selective commit"

    Ok, let me try. I used nested data contexts because Philip advised me so ;-)

    Andrus Adamchik escribió:
    > 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 : Wed Jan 09 2008 - 03:29:36 EST