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.)
>
>
>