我目前正在使用嵌入式模式的Java Graph API评估OrientDB,以便在将来的项目中使用。在分布式设置中使用事务图实现时,我正在观察以下问题:
在第一个节点上,我按如下方式设置了一个简单的模式:
graph.getRawGraph().commit();
if (graph.getVertexType("Person") == null)
graph.createVertexType("Person");
final OrientVertexType vtPerson = graph.getVertexType("Person");
if (vtPerson.getProperty("firstName") == null)
vtPerson.createProperty("firstName", OType.STRING);
if (vtPerson.getProperty("lastName") == null)
vtPerson.createProperty("lastName", OType.STRING);
vtPerson.createEdgeProperty(Direction.OUT, "lives");
vtPerson.createEdgeProperty(Direction.OUT, "history");
vtPerson.setStrictMode(true);
在第一个节点上,我尝试添加一个顶点:
try {
final OrientVertex person = graph.addVertex("class:Person", "firstName", firstName, "lastName", lastName);
graph.getRawGraph().commit();
return person;
} catch (Exception e) {
e.printStackTrace();
graph.rollback();
}
那是我得到OSchemaException的时候:
com.orientechnologies.orient.core.exception.OSchemaException: Cannot change the schema while a transaction is active. Schema changes are not transactional
DB name="test"
at com.orientechnologies.orient.core.metadata.schema.OSchemaShared.saveInternal(OSchemaShared.java:1284)
at com.orientechnologies.orient.core.metadata.schema.OSchemaShared.releaseSchemaWriteLock(OSchemaShared.java:606)
at com.orientechnologies.orient.core.metadata.schema.OClassImpl.releaseSchemaWriteLock(OClassImpl.java:2028)
at com.orientechnologies.orient.core.metadata.schema.OClassImpl.releaseSchemaWriteLock(OClassImpl.java:2023)
at com.orientechnologies.orient.core.metadata.schema.OClassImpl.setClusterSelectionInternal(OClassImpl.java:2062)
at com.orientechnologies.orient.server.distributed.impl.ODistributedAbstractPlugin.propagateSchemaChanges(ODistributedAbstractPlugin.java:1439)
at com.orientechnologies.orient.server.distributed.impl.ODistributedStorage.checkForCluster(ODistributedStorage.java:1803)
at com.orientechnologies.orient.server.distributed.impl.ODistributedTransactionManager.checkForClusterIds(ODistributedTransactionManager.java:275)
at com.orientechnologies.orient.server.distributed.impl.ODistributedTransactionManager.commit(ODistributedTransactionManager.java:87)
at com.orientechnologies.orient.server.distributed.impl.ODistributedStorage.commit(ODistributedStorage.java:1240)
at com.orientechnologies.orient.core.tx.OTransactionOptimistic.doCommit(OTransactionOptimistic.java:569)
at com.orientechnologies.orient.core.tx.OTransactionOptimistic.commit(OTransactionOptimistic.java:109)
at com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx.commit(ODatabaseDocumentTx.java:2667)
at com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx.commit(ODatabaseDocumentTx.java:2637)
使用OrientGraphNoTx实现时,一切都按预期工作。但是,我更喜欢使用事务图,以便能够回滚事务。
答案 0 :(得分:2)
这是正确的 - Orient中的架构更改不是事务性的。您应该使用非事务性操作来创建或修改模式,并使用事务操作来对图形进行数据更改。
如果您需要在业务逻辑中执行架构更改,请先运行它们,如果它们失败,也会使数据事务失败。重要的是要注意,在某些情况下,如果使用事务上下文执行架构更改,OrientDB将默默提交正在进行的事务,因此请确保从不执行此操作。
答案 1 :(得分:1)
Where exactly am I performing a schema change, when adding a new Vertex?
架构更改在此if
块中完成。 createVertexType("Person")
更改架构。
if (graph.getVertexType("Person") == null)
graph.createVertexType("Person");
当您使用上述提及的电话factory.getTx()
时,您正在使用交易。
OrientGraphFactory::factory.getTx()
相反,请尝试
graph = new OrientGraphNoTx("your URL");
并点击此处: Create schema for graph database with Java in OrientDB