Neo4j通过蓝图在使用不同的线程时卡住了

时间:2014-08-14 12:49:00

标签: neo4j deadlock tinkerpop

我正在使用来自maven存储库的blueprints-neo4j-graph-2.5.0。

在使用来自不同线程的图表时,neo4j会冻结。重新创建问题的代码,以及附加的调用堆栈。任何有关此问题或任何使用模式的决议都将受到高度赞赏。

public class Simplest {

    public static void main(String[] args) {
        new Simplest();
    }

    Graph g = new Neo4jGraph("E:/temp/neoTest");
    Vertex a = g.addVertex(null);

    public Simplest() { 
        new Thread(new Runnable() {
            @Override
            public void run() {
                Vertex b = g.addVertex(null);
                a.addEdge("relation", b);
                System.out.println("never reaches here...");
            }
        }).start();
    }

}

跟踪堆栈跟踪......

Thread [Thread-2] (Suspended)   
    waiting for: RWLock  (id=43)    
    Object.wait(long) line: not available [native method]   
    RWLock(Object).wait() line: 503 
    RWLock.deadlockGuardedWait(Transaction, RWLock$TxLockElement, LockType) line: 652   
    RWLock.acquireWriteLock(Transaction) line: 344  
    LockManagerImpl.getWriteLock(Object, Transaction) line: 84  
    LockManagerImpl.getWriteLock(Object) line: 77   
    WritableTransactionState.acquireWriteLock(Object) line: 269 
    LockType$2.acquire(TransactionState, Object) line: 51   
    NodeManager.getNodeForProxy(long, LockType) line: 473   
    InternalAbstractGraphDatabase$8.lookup(long, LockType) line: 791    
    NodeProxy.createRelationshipTo(Node, RelationshipType) line: 207    
    Neo4jGraph.addEdge(Object, Vertex, Vertex, String) line: 487    
    Neo4jVertex.addEdge(String, Vertex) line: 47    
    Simplest$1.run() line: 24   
    Thread.run() line: not available    

2 个答案:

答案 0 :(得分:1)

蓝图似乎将当前事务与当前线程相关联。所以在使用另一个线程的图表之前必须先关闭它。 TransactionalGraph.commit()关闭当前的交易。以下作品。

public class Simplest {

    public static void main(String[] args) {
        new Simplest();
    }

    Neo4jGraph g;
    Vertex a;

    {
        g = new Neo4jGraph("E:/temp/neoTest");
        a = g.addVertex(null);
        g.commit();
    }

    public Simplest() {
        new Thread(new Runnable() {
            public void run() {
                Vertex b = g.addVertex(null);
                a.addEdge("relation", b);
                g.commit();
                System.out.println("now reaches here...");
            }
        }).start();
    }

}

答案 1 :(得分:0)

我认为您应该使用显式事务管理,而不是依赖于蓝图中的隐式事务处理。最好禁用自动交易,只需通过neo4jGraph.beginTransaction()手动管理它们或者调用该功能。