cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Andrus Adamchik (Updated) (JIRA)" <j...@apache.org>
Subject [jira] [Updated] (CAY-957) Deadlock in nested contexts
Date Mon, 23 Jan 2012 21:19:40 GMT

     [ https://issues.apache.org/jira/browse/CAY-957?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

Andrus Adamchik updated CAY-957:
--------------------------------

    Description: 
There is a deadlock condition when two peer nested contexts commit simultaneously. The test
case (attached as a patch) deadlocks almost immediately with only two threads... 

The old (pre CAY-1653 stack) :

Name: UpdateThread-9684455
State: BLOCKED on org.apache.cayenne.event.DispatchQueue@f899e9 owned by: UpdateThread-10872036
Total blocked: 7  Total waited: 1

Stack trace: 
org.apache.cayenne.event.DispatchQueue.dispatchEvent(DispatchQueue.java:54)
org.apache.cayenne.event.EventManager.dispatchEvent(EventManager.java:348)
org.apache.cayenne.event.EventManager.postEvent(EventManager.java:319)
org.apache.cayenne.access.DataContext.fireDataChannelChanged(DataContext.java:1457)
org.apache.cayenne.access.DataContext.onContextFlush(DataContext.java:1121)
org.apache.cayenne.access.DataContext.onSync(DataContext.java:1102)
org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:1160)
org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:1073)
org.test.Main$UpdateThread.run(Main.java:66)



Name: UpdateThread-10872036
State: BLOCKED on org.apache.cayenne.access.ObjectStore@1b9b03 owned by: UpdateThread-9684455
Total blocked: 9  Total waited: 0

Stack trace: 
org.apache.cayenne.access.DataContextMergeHandler.graphChanged(DataContextMergeHandler.java:104)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:585)
org.apache.cayenne.util.Invocation.fire(Invocation.java:204)
org.apache.cayenne.event.EventManager$Dispatch.fire(EventManager.java:409)
org.apache.cayenne.event.DispatchQueue.dispatchEvent(DispatchQueue.java:162)
org.apache.cayenne.event.DispatchQueue.dispatchEvent(DispatchQueue.java:58)
org.apache.cayenne.event.EventManager.dispatchEvent(EventManager.java:348)
org.apache.cayenne.event.EventManager.postEvent(EventManager.java:319)
org.apache.cayenne.access.DataContext.fireDataChannelChanged(DataContext.java:1457)
org.apache.cayenne.access.DataContext.onContextFlush(DataContext.java:1121)
org.apache.cayenne.access.DataContext.onSync(DataContext.java:1102)
org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:1160)
org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:1073)
org.test.Main$UpdateThread.run(Main.java:66)

Newer stack is shown below in comments.


  was:
There is a deadlock condition when two peer nested contexts commit simultaneously. Here is
a small test case:

package org.test;

import java.util.Date;
import java.util.List;
import java.util.Random;

import org.apache.cayenne.access.DataContext;
import org.apache.cayenne.query.EJBQLQuery;

public class Main {

	public static void main(String[] args) {
		DataContext parent = DataContext.createDataContext();

		parent.performGenericQuery(new EJBQLQuery("delete from Artist"));

		for (int i = 0; i < 300; i++) {
			Artist a = parent.newObject(Artist.class);
			a.setArtistName("X" + i);
			a.setDateOfBirth(new Date());
		}

		parent.commitChanges();

		Random rnd = new Random(System.currentTimeMillis());
		for (int i = 0; i < 2; i++) {
			new UpdateThread(parent.createChildDataContext(), rnd).start();
		}

		synchronized (parent) {
			try {
				parent.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

	static class UpdateThread extends Thread {
		protected DataContext context;
		protected Random rnd;

		UpdateThread(DataContext context, Random rnd) {
			super("UpdateThread-" + context.hashCode());
			setDaemon(true);
			this.context = context;
			this.rnd = rnd;
		}

		@Override
		public void run() {

			List<Artist> artists = context.performQuery(new EJBQLQuery(
					"select a FROM Artist a"));

			for (int i = 0; i < 1000; i++) {

				for (int j = 0; j < 5; j++) {
					int index = rnd.nextInt(artists.size());
					Artist a = artists.get(index);
					a.setArtistName("Y" + rnd.nextInt());
				}

				context.commitChanges();
				System.out.println(getId() + ": " + i);
			}
		}
	}
}


It deadlocks almost immediately with only two threads... Here is the stacks from Jconsole:

Name: UpdateThread-9684455
State: BLOCKED on org.apache.cayenne.event.DispatchQueue@f899e9 owned by: UpdateThread-10872036
Total blocked: 7  Total waited: 1

Stack trace: 
org.apache.cayenne.event.DispatchQueue.dispatchEvent(DispatchQueue.java:54)
org.apache.cayenne.event.EventManager.dispatchEvent(EventManager.java:348)
org.apache.cayenne.event.EventManager.postEvent(EventManager.java:319)
org.apache.cayenne.access.DataContext.fireDataChannelChanged(DataContext.java:1457)
org.apache.cayenne.access.DataContext.onContextFlush(DataContext.java:1121)
org.apache.cayenne.access.DataContext.onSync(DataContext.java:1102)
org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:1160)
org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:1073)
org.test.Main$UpdateThread.run(Main.java:66)



Name: UpdateThread-10872036
State: BLOCKED on org.apache.cayenne.access.ObjectStore@1b9b03 owned by: UpdateThread-9684455
Total blocked: 9  Total waited: 0

Stack trace: 
org.apache.cayenne.access.DataContextMergeHandler.graphChanged(DataContextMergeHandler.java:104)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:585)
org.apache.cayenne.util.Invocation.fire(Invocation.java:204)
org.apache.cayenne.event.EventManager$Dispatch.fire(EventManager.java:409)
org.apache.cayenne.event.DispatchQueue.dispatchEvent(DispatchQueue.java:162)
org.apache.cayenne.event.DispatchQueue.dispatchEvent(DispatchQueue.java:58)
org.apache.cayenne.event.EventManager.dispatchEvent(EventManager.java:348)
org.apache.cayenne.event.EventManager.postEvent(EventManager.java:319)
org.apache.cayenne.access.DataContext.fireDataChannelChanged(DataContext.java:1457)
org.apache.cayenne.access.DataContext.onContextFlush(DataContext.java:1121)
org.apache.cayenne.access.DataContext.onSync(DataContext.java:1102)
org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:1160)
org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:1073)
org.test.Main$UpdateThread.run(Main.java:66)




    
> Deadlock in nested contexts
> ---------------------------
>
>                 Key: CAY-957
>                 URL: https://issues.apache.org/jira/browse/CAY-957
>             Project: Cayenne
>          Issue Type: Bug
>          Components: Core Library
>    Affects Versions: 1.2 branch, 2.0 branch, 3.0
>            Reporter: Andrus Adamchik
>            Assignee: Andrus Adamchik
>             Fix For: Short term future
>
>         Attachments: 0001-CAY-957-Deadlock-in-nested-contexts.patch
>
>
> There is a deadlock condition when two peer nested contexts commit simultaneously. The
test case (attached as a patch) deadlocks almost immediately with only two threads... 
> The old (pre CAY-1653 stack) :
> Name: UpdateThread-9684455
> State: BLOCKED on org.apache.cayenne.event.DispatchQueue@f899e9 owned by: UpdateThread-10872036
> Total blocked: 7  Total waited: 1
> Stack trace: 
> org.apache.cayenne.event.DispatchQueue.dispatchEvent(DispatchQueue.java:54)
> org.apache.cayenne.event.EventManager.dispatchEvent(EventManager.java:348)
> org.apache.cayenne.event.EventManager.postEvent(EventManager.java:319)
> org.apache.cayenne.access.DataContext.fireDataChannelChanged(DataContext.java:1457)
> org.apache.cayenne.access.DataContext.onContextFlush(DataContext.java:1121)
> org.apache.cayenne.access.DataContext.onSync(DataContext.java:1102)
> org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:1160)
> org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:1073)
> org.test.Main$UpdateThread.run(Main.java:66)
> Name: UpdateThread-10872036
> State: BLOCKED on org.apache.cayenne.access.ObjectStore@1b9b03 owned by: UpdateThread-9684455
> Total blocked: 9  Total waited: 0
> Stack trace: 
> org.apache.cayenne.access.DataContextMergeHandler.graphChanged(DataContextMergeHandler.java:104)
> sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> java.lang.reflect.Method.invoke(Method.java:585)
> org.apache.cayenne.util.Invocation.fire(Invocation.java:204)
> org.apache.cayenne.event.EventManager$Dispatch.fire(EventManager.java:409)
> org.apache.cayenne.event.DispatchQueue.dispatchEvent(DispatchQueue.java:162)
> org.apache.cayenne.event.DispatchQueue.dispatchEvent(DispatchQueue.java:58)
> org.apache.cayenne.event.EventManager.dispatchEvent(EventManager.java:348)
> org.apache.cayenne.event.EventManager.postEvent(EventManager.java:319)
> org.apache.cayenne.access.DataContext.fireDataChannelChanged(DataContext.java:1457)
> org.apache.cayenne.access.DataContext.onContextFlush(DataContext.java:1121)
> org.apache.cayenne.access.DataContext.onSync(DataContext.java:1102)
> org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:1160)
> org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:1073)
> org.test.Main$UpdateThread.run(Main.java:66)
> Newer stack is shown below in comments.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Mime
View raw message