You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cayenne.apache.org by Álvaro Martínez <al...@ptbsl.com> on 2008/01/07 13:44:06 UTC
Selective commit
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.)
Re: Selective commit
Posted by Álvaro Martínez <al...@ptbsl.com>.
No problem, let me try
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
>
Re: Selective commit
Posted by Andrus Adamchik <an...@objectstyle.org>.
Great!
Also good that we found the deadlock condition. Usually nested
contexts are used in a (semi)single-threaded environment, e.g. to
provide local "savepoints" for nested Swing dialogs, or in a "context-
per-web-request" situation with the same goal to avoid committing the
main context between multiple requests... So this got overlooked. Now
I was able to easily reproduce the condition:
https://issues.apache.org/cayenne/browse/CAY-957
Will work on fixing it, but also good to know that there's not much
urgency in that.
Thanks,
Andrus
On Jan 9, 2008, at 10:51 AM, Álvaro Martínez wrote:
>
> Using brand new data contexts solved the problem! I just replaced
> this function:
>
> public DataContext getNewContext() {
> DataContext newContext = context.createChildDataContext();
> newContext.setTransactionEventsEnabled(true);
> newContext.setValidatingObjectsOnCommit(true);
> return newContext;
> }
>
> With this one:
>
> public DataContext getNewContext() {
> return DataContext.createDataContext(true);
> }
>
> And everything is ok now. I didn't touch any other piece of code.
>
> Thank you very much!
>
>
>
> 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
>
>
Re: Selective commit
Posted by Álvaro Martínez <al...@ptbsl.com>.
Using brand new data contexts solved the problem! I just replaced this
function:
public DataContext getNewContext() {
DataContext newContext = context.createChildDataContext();
newContext.setTransactionEventsEnabled(true);
newContext.setValidatingObjectsOnCommit(true);
return newContext;
}
With this one:
public DataContext getNewContext() {
return DataContext.createDataContext(true);
}
And everything is ok now. I didn't touch any other piece of code.
Thank you very much!
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
Re: Selective commit
Posted by Álvaro Martínez <al...@ptbsl.com>.
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.ObjectStore@c9f698 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.DispatchQueue@15c80d8
>>> 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.ObjectStore@b92a34
>>> 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.DispatchQueue@15c80d8
>>> 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.ObjectStore@c9f698
>>> org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:1138)
>>>
>>> com.ptb.confignode.ConfigNode.newConfigGenerated(ConfigNode.java:711)
>>> - locked java.lang.Boolean@5f6d5a
>>> 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.DispatchQueue@c25268
>>>>>>> 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.DispatchQueue@12d553e
>>>>>>> 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.ObjectStore@137958b
>>>>>>> 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.ObjectStore@1b3a10d
>>>>>>> org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:1138)
>>>>>>>
>>>>>>> com.ptb.confignode.ConfigNode.newConfigGenerated(ConfigNode.java:711)
>>>>>>>
>>>>>>> - locked java.lang.Boolean@3b13c5
>>>>>>> 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.ObjectStore@1b3a10d
>>>>>>> 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.DispatchQueue@c25268
>>>>>>> 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.ObjectStore@a86d2f
>>>>>>> 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
>>>>>>>> <al...@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.)
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>
>>
>>
>
>
Re: Selective commit
Posted by Andrus Adamchik <an...@objectstyle.org>.
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.ObjectStore@c9f698
>> 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.DispatchQueue@15c80d8
>> 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.ObjectStore@b92a34
>> 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.DispatchQueue@15c80d8
>> 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.ObjectStore@c9f698
>> org
>> .apache.cayenne.access.DataContext.commitChanges(DataContext.java:
>> 1138)
>> com.ptb.confignode.ConfigNode.newConfigGenerated(ConfigNode.java:711)
>> - locked java.lang.Boolean@5f6d5a
>> 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.DispatchQueue@c25268
>>>>>> 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.DispatchQueue@12d553e
>>>>>> 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.ObjectStore@137958b
>>>>>> 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.ObjectStore@1b3a10d
>>>>>> org
>>>>>> .apache
>>>>>> .cayenne.access.DataContext.commitChanges(DataContext.java:1138)
>>>>>> com
>>>>>> .ptb.confignode.ConfigNode.newConfigGenerated(ConfigNode.java:
>>>>>> 711)
>>>>>> - locked java.lang.Boolean@3b13c5
>>>>>> 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.ObjectStore@1b3a10d
>>>>>> 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.DispatchQueue@c25268
>>>>>> 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.ObjectStore@a86d2f
>>>>>> 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.)
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>>
>>>
>>
>
>
Re: Selective commit
Posted by Andrus Adamchik <an...@objectstyle.org>.
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.ObjectStore@c9f698 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.DispatchQueue@15c80d8
> 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.ObjectStore@b92a34
> 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.DispatchQueue@15c80d8
> 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.ObjectStore@c9f698
> org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:
> 1138)
> com.ptb.confignode.ConfigNode.newConfigGenerated(ConfigNode.java:711)
> - locked java.lang.Boolean@5f6d5a
> 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.DispatchQueue@c25268
>>>>> 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.DispatchQueue@12d553e
>>>>> 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.ObjectStore@137958b
>>>>> 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.ObjectStore@1b3a10d
>>>>> org
>>>>> .apache
>>>>> .cayenne.access.DataContext.commitChanges(DataContext.java:1138)
>>>>> com.ptb.confignode.ConfigNode.newConfigGenerated(ConfigNode.java:
>>>>> 711)
>>>>> - locked java.lang.Boolean@3b13c5
>>>>> 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.ObjectStore@1b3a10d
>>>>> 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.DispatchQueue@c25268
>>>>> 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.ObjectStore@a86d2f
>>>>> 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.)
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>>
>
Re: Selective commit
Posted by Andrus Adamchik <an...@objectstyle.org>.
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.DispatchQueue@c25268
>>> 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.DispatchQueue@12d553e
>>> 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.ObjectStore@137958b
>>> 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.ObjectStore@1b3a10d
>>> org
>>> .apache.cayenne.access.DataContext.commitChanges(DataContext.java:
>>> 1138)
>>> com.ptb.confignode.ConfigNode.newConfigGenerated(ConfigNode.java:
>>> 711)
>>> - locked java.lang.Boolean@3b13c5
>>> 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.ObjectStore@1b3a10d
>>> 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.DispatchQueue@c25268
>>> 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.ObjectStore@a86d2f
>>> 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
>>>> <al...@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.)
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>
>>>>
>>>
>>
>>
>>
>
>
Re: Selective commit
Posted by Álvaro Martínez <al...@ptbsl.com>.
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.DispatchQueue@c25268 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.DispatchQueue@12d553e
>> 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.ObjectStore@137958b
>> 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.ObjectStore@1b3a10d
>> org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:1138)
>>
>> com.ptb.confignode.ConfigNode.newConfigGenerated(ConfigNode.java:711)
>> - locked java.lang.Boolean@3b13c5
>> 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.ObjectStore@1b3a10d 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.DispatchQueue@c25268
>> 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.ObjectStore@a86d2f
>> 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 <al...@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.)
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>>
>>
>
>
>
Re: Selective commit
Posted by Andrus Adamchik <an...@objectstyle.org>.
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.DispatchQueue@c25268
> 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.DispatchQueue@12d553e
> 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.ObjectStore@137958b
> 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.ObjectStore@1b3a10d
> org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:
> 1138)
> com.ptb.confignode.ConfigNode.newConfigGenerated(ConfigNode.java:711)
> - locked java.lang.Boolean@3b13c5
> 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.ObjectStore@1b3a10d
> 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.DispatchQueue@c25268
> 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.ObjectStore@a86d2f
> 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
>> <al...@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.)
>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>
>>
>
Re: Selective commit
Posted by Michael Gentry <bl...@gmail.com>.
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 <al...@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.)
> >>
> >>
> >>
> >
> >
> >
>
>
Re: Selective commit
Posted by Álvaro Martínez <al...@ptbsl.com>.
Ok, I'll do that! :-D
Andrus Adamchik escribió:
> It's not that expensive (each context attaches to a shared stack) and
> looks like the best strategy in your case.
>
> One possible optimization is to use a single shared DataContext for
> read-only operations, and create a new DataContext for each operation
> that is expected to modify and commit the objects. It is only possible
> of course if you have any "read-only" operations at all.
>
> Andrus
>
>
> On Jan 7, 2008, at 5:30 PM, Álvaro Martínez 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.)
>>>>
>>>>
>>>>
>>>
>>>
>>>
>>
>>
>
>
>
Re: Selective commit
Posted by Andrus Adamchik <an...@objectstyle.org>.
It's not that expensive (each context attaches to a shared stack) and
looks like the best strategy in your case.
One possible optimization is to use a single shared DataContext for
read-only operations, and create a new DataContext for each operation
that is expected to modify and commit the objects. It is only possible
of course if you have any "read-only" operations at all.
Andrus
On Jan 7, 2008, at 5:30 PM, Álvaro Martínez 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.)
>>>
>>>
>>>
>>
>>
>>
>
>
Re: Selective commit
Posted by Álvaro Martínez <al...@ptbsl.com>.
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.)
>>
>>
>>
>
>
>
Re: Selective commit
Posted by Andrus Adamchik <an...@objectstyle.org>.
Yeah, I understood the hint :-)
On Jan 7, 2008, at 5:10 PM, Philip Miller wrote:
> That nudge should have been for rollbackChangesLocally() - CAY-716.
> Sorry Andrus.
>
>> -----Original Message-----
>> From: Philip Miller [mailto:philip.miller@bbc.co.uk]
>> Sent: 07 January 2008 14:29
>> To: user@cayenne.apache.org
>> Subject: RE: Selective commit
>>
>> Nested data contexts may also help you to isolate atomic
>> changes to the object graph. Especially when the
>> commitChangesLocally() method is implemented (nudge ;). Check
>> out DataContext.createChildDataContext().
>>
>>
>>
>>> -----Original Message-----
>>> From: Andrus Adamchik [mailto:andrus@objectstyle.org]
>>> Sent: 07 January 2008 13:32
>>> To: user@cayenne.apache.org
>>> Subject: Re: Selective commit
>>>
>>> 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.)
>>>>
>>>>
>>>>
>>>
>>>
>>
>> http://www.bbc.co.uk/
>> This e-mail (and any attachments) is confidential and may
>> contain personal views which are not the views of the BBC
>> unless specifically stated.
>> If you have received it in error, please delete it from your system.
>> Do not use, copy or disclose the information in any way nor
>> act in reliance on it and notify the sender immediately.
>> Please note that the BBC monitors e-mails sent or received.
>> Further communication will signify your consent to this.
>>
>>
>
> http://www.bbc.co.uk/
> This e-mail (and any attachments) is confidential and may contain
> personal views which are not the views of the BBC unless
> specifically stated.
> If you have received it in error, please delete it from your system.
> Do not use, copy or disclose the information in any way nor act in
> reliance on it and notify the sender immediately.
> Please note that the BBC monitors e-mails sent or received.
> Further communication will signify your consent to this.
>
>
RE: Selective commit
Posted by Philip Miller <ph...@bbc.co.uk>.
That nudge should have been for rollbackChangesLocally() - CAY-716. Sorry Andrus.
> -----Original Message-----
> From: Philip Miller [mailto:philip.miller@bbc.co.uk]
> Sent: 07 January 2008 14:29
> To: user@cayenne.apache.org
> Subject: RE: Selective commit
>
> Nested data contexts may also help you to isolate atomic
> changes to the object graph. Especially when the
> commitChangesLocally() method is implemented (nudge ;). Check
> out DataContext.createChildDataContext().
>
>
>
> > -----Original Message-----
> > From: Andrus Adamchik [mailto:andrus@objectstyle.org]
> > Sent: 07 January 2008 13:32
> > To: user@cayenne.apache.org
> > Subject: Re: Selective commit
> >
> > 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.)
> > >
> > >
> > >
> >
> >
>
> http://www.bbc.co.uk/
> This e-mail (and any attachments) is confidential and may
> contain personal views which are not the views of the BBC
> unless specifically stated.
> If you have received it in error, please delete it from your system.
> Do not use, copy or disclose the information in any way nor
> act in reliance on it and notify the sender immediately.
> Please note that the BBC monitors e-mails sent or received.
> Further communication will signify your consent to this.
>
>
http://www.bbc.co.uk/
This e-mail (and any attachments) is confidential and may contain personal views which are not the views of the BBC unless specifically stated.
If you have received it in error, please delete it from your system.
Do not use, copy or disclose the information in any way nor act in reliance on it and notify the sender immediately.
Please note that the BBC monitors e-mails sent or received.
Further communication will signify your consent to this.
RE: Selective commit
Posted by Philip Miller <ph...@bbc.co.uk>.
Nested data contexts may also help you to isolate atomic changes to the object graph. Especially when the commitChangesLocally() method is implemented (nudge ;). Check out DataContext.createChildDataContext().
> -----Original Message-----
> From: Andrus Adamchik [mailto:andrus@objectstyle.org]
> Sent: 07 January 2008 13:32
> To: user@cayenne.apache.org
> Subject: Re: Selective commit
>
> 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.)
> >
> >
> >
>
>
http://www.bbc.co.uk/
This e-mail (and any attachments) is confidential and may contain personal views which are not the views of the BBC unless specifically stated.
If you have received it in error, please delete it from your system.
Do not use, copy or disclose the information in any way nor act in reliance on it and notify the sender immediately.
Please note that the BBC monitors e-mails sent or received.
Further communication will signify your consent to this.
Re: Selective commit
Posted by Andrus Adamchik <an...@objectstyle.org>.
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.)
>
>
>