这是"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;如果一个线程删除边缘而另一个线程添加第二个边缘,则该语句是真的吗?
出于好奇。
答案 0 :(得分:1)
这里的问题是你在两个不同的线程中使用相同的db实例,你应该避免这种情况,因为db不是线程安全的。
当您从两个不同的进程更新相同的顶点时,可能会发生OConcurrentModificationException。这是一个技术细节:如果一个顶点的边缘少于40个(它是一个可配置的阈值),边缘指针存储在顶点文档中,因此添加边缘也会导致顶点版本的增加。超过此阈值边缘存储在外部结构(SBTreeBonsai)中,因此边缘添加不会导致顶点版本增加;在这种情况下,您没有OConcurrentModificationException。 只需确保获取两个不同的顶点实例,并且不能在两个线程的同一对象上进行并发操作,否则会导致问题。