Re: Selective commit

From: Andrus Adamchik (andru..bjectstyle.org)
Date: Tue Jan 08 2008 - 09:13:50 EST

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

    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 - 09:14:23 EST