Transactions 是否可以在一个原子步骤中在图形数据库中执行图形遍历?

Transactions 是否可以在一个原子步骤中在图形数据库中执行图形遍历?,transactions,neo4j,orientdb,graph-databases,arangodb,Transactions,Neo4j,Orientdb,Graph Databases,Arangodb,在一个附带项目中,我正在研究用于存储树的基于图形的数据库。 存储和阅读它们并不是一个大问题(毫不奇怪),但现在看来我已经走到了死胡同。 这些树将由网页存储和读取,因此两者可能同时发生。现在,由于写事务是一个常见的功能,所以几个存储进程之间不会相互干扰 另一方面,如果在另一个进程遍历节点时提交了一个写事务,则结果将是错误的 例如,假设一个人打开带有树的网页,编辑它并提交更改。同时,其他人打开页面,以便在提交时从数据库中读取该页面 为了从数据库中读取树,我首先遍历节点深度,然后根据结果构建一个jso

在一个附带项目中,我正在研究用于存储树的基于图形的数据库。 存储和阅读它们并不是一个大问题(毫不奇怪),但现在看来我已经走到了死胡同。 这些树将由网页存储和读取,因此两者可能同时发生。现在,由于写事务是一个常见的功能,所以几个存储进程之间不会相互干扰

另一方面,如果在另一个进程遍历节点时提交了一个写事务,则结果将是错误的

例如,假设一个人打开带有树的网页,编辑它并提交更改。同时,其他人打开页面,以便在提交时从数据库中读取该页面

为了从数据库中读取树,我首先遍历节点深度,然后根据结果构建一个json对象。因此,有时会发生这样的情况:如果一个节点从一个分支移动到另一个分支,它会被读取两次,因为它是在旧位置读取的,当读取过程到达新位置时,提交已经发生

我现在正在使用OrientDB,还没有找到解决方案。Java API和Tinkerpop Gremlin都以单个调用的形式执行遍历,因此我认为没有任何理由相信服务器会锁定数据。从我读到的内容来看,ArrangoDb也是如此,在Neo4j的文档中,它明确指出:“通过遍历检索的数据不受其他事务修改的保护。”()

这是图形数据库的一般问题还是我使用数据库不正确?
对于OrientDb,我可能会尝试使用SQL语法,但我看不出有任何理由相信这会解决问题。

这里只谈Neo4j,不能评论其他事务:一个事务可以在另一个事务遍历同一区域时修改图。但有一种方法可以防止这种情况:抓取显式锁

该接口包含获取锁的方法。如果执行遍历的事务具有锁,它将阻止这些事务上的并发写入

Cypher(neo4j查询语言)没有显式获取锁的方法。建议的解决方法是设置一个伪属性并最终将其删除-作为一个副作用,我们将保留一个锁:

MATCH (n:Person {name:'myself'})
SET n._fake = 1
WITH n
....  do more stuff
REMOVE n._fake
RETURN <whateverresult>
MATCH(n:Person{name:'imf'})
设置n._fake=1
与n
....  多做事
除去n.(u)伪
返回

很有趣。因此,为了创建读锁,您需要在您想要访问的节点组所特有的实体上设置写锁。因此,在我的例子中,我可能会在树的根节点上设置一些伪值,以便我的读遍历包含在写事务中。我看到的唯一缺点是,这也不允许并发读取,对吗?再想一想——由于OrientDB和ArangoDB都具有MVCC特性,因此启动一个事务并在开始时获得这样一个“假”写锁就足够了,然后永远不要提交不必要的更改。我去看看。