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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED]
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 [EMAIL PROTECTED]
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 [EMAIL PROTECTED]
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 [EMAIL PROTECTED]
org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:
1138)
com.ptb.confignode.ConfigNode.newConfigGenerated(ConfigNode.java:711)
- locked [EMAIL PROTECTED]
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 [EMAIL PROTECTED]
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 [EMAIL PROTECTED]
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 [EMAIL PROTECTED]
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 [EMAIL PROTECTED]
org
.apache
.cayenne.access.DataContext.commitChanges(DataContext.java:1138)
com.ptb.confignode.ConfigNode.newConfigGenerated(ConfigNode.java:
711)
- locked [EMAIL PROTECTED]
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 [EMAIL PROTECTED]
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 [EMAIL PROTECTED]
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 [EMAIL PROTECTED]
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 <[EMAIL PROTECTED]
> 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.)