Re: Selective commit

From: Álvaro Martínez (alvaro_martine..tbsl.com)
Date: Tue Jan 08 2008 - 10:16:00 EST

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



    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_martinez@ptbsl.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:16:45 EST