相同的顶点/查询抛出并且不会根据调用线程抛出NPE

时间:2015-10-23 02:59:26

标签: orientdb

这是"Transaction was rolled back more times than it was started" Exception?

的延续

我设法缩小了自从我开始使用OrientGraphFactory以来遇到的一些问题(意味着在我使用OrientGraph并且没有看到这个NPE之前)

package oThread;

import java.io.File;
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.orient.OrientGraph;
import com.tinkerpop.blueprints.impls.orient.OrientGraphFactory;

public class OThread {
    public static void main(String[] args){
        File f = new File(System.getProperty("user.home"), "oThread");
        f.mkdir();          
        OrientGraphFactory factory = new OrientGraphFactory("plocal:" + System.getProperty("user.home") + File.separatorChar + "oThread").setupPool(1, 10);
        factory.setAutoStartTx(false);
        final Vertex v1;
        final OrientGraph g = factory.getTx();
        g.begin();
        v1 = g.addVertex(null);
        g.commit();
        Thread t = new Thread(new Runnable(){
            public void run(){
                try{
                    v1.query().direction(Direction.OUT).labels("currentSuite").has("ID", 0).edges().iterator().hasNext();
                }
                catch(Exception x){
                    x.toString();
                }
            }
        });
        t.start();
        try {
             v1.query().direction(Direction.OUT).labels("currentSuite").has("ID", 0).edges().iterator().hasNext();
            t.join();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

线程内的查询抛出NPE,而线程外的查询则没有。

堆栈跟踪是

java.lang.NullPointerException
    at com.tinkerpop.blueprints.impls.orient.OrientBaseGraph.getEdgeClassNames(OrientBaseGraph.java:307)
    at com.tinkerpop.blueprints.impls.orient.OrientVertex.getEdges(OrientVertex.java:1005)
    at com.tinkerpop.blueprints.impls.orient.OrientVertex.getEdges(OrientVertex.java:988)
    at com.tinkerpop.blueprints.util.DefaultVertexQuery$DefaultVertexQueryIterable.<init>(DefaultVertexQuery.java:110)
    at com.tinkerpop.blueprints.util.DefaultVertexQuery.edges(DefaultVertexQuery.java:80)
    at oThread.OThread$1.run(OThread.java:28)
    at java.lang.Thread.run(Thread.java:745)

jvm 1.7.0_79 orientdb 2.0.12 CE。 OS X 10.9

任何线索?非常感谢提前!

更新:

似乎通过向工厂询问另一个Graph实例并检索在查询未失败之前创建的顶点。我可以解决这个问题。

问题:

&#34;当多个客户端在同一个顶点上添加边时会发生什么? OrientDB也可以抛出OConcurrentModificationException异常&#34;如果一个线程删除边缘而另一个线程添加第二个边缘,则该语句是真的吗?

出于好奇。

1 个答案:

答案 0 :(得分:1)

这里的问题是你在两个不同的线程中使用相同的db实例,你应该避免这种情况,因为db不是线程安全的。

当您从两个不同的进程更新相同的顶点时,可能会发生OConcurrentModificationException。这是一个技术细节:如果一个顶点的边缘少于40个(它是一个可配置的阈值),边缘指针存储在顶点文档中,因此添加边缘也会导致顶点版本的增加。超过此阈值边缘存储在外部结构(SBTreeBonsai)中,因此边缘添加不会导致顶点版本增加;在这种情况下,您没有OConcurrentModificationException。 只需确保获取两个不同的顶点实例,并且不能在两个线程的同一对象上进行并发操作,否则会导致问题。