【问题标题】:Is it possible to execute read only cypher queries from java?是否可以从 java 执行只读密码查询?
【发布时间】:2015-03-12 19:01:28
【问题描述】:

我想知道标题是什么意思。

我想要这样做的原因是允许执行受限的只读密码查询;数据结果稍后将由单独的 API 层解释和序列化。

我见过一些代码做出基本假设以试图模仿这种行为,例如该代码可能会过滤掉包含与写入查询结构相关的某些特殊单词的任何 Cypher 查询(mergecreatedeleteset 等)。

但这种方法往往是有限且幼稚的;如果它非常简单地查找这些标记,它将阻止像 MATCH n WHERE n.label =~ '.*create.*' RETURN n 这样的查询,即使它是一个只读查询。

我真的不希望对候选查询进行完整解析,然后通过 AST 下降试图确定某些内容是否为只读(尽管我很乐意接受显示如何执行此操作的答案在java中很容易)

EDIT - 我知道可以通过配置属性read_only=true 以只读模式启动整个数据库,但这是不可取的; Java API 的其他方面都无法更改数据库。

EDIT 2 - 我找到了另一种可能的策略,但我不确定它是否可取。欢迎对此发表评论,以及潜在的缺点:

try (Transaction ignore = graphDb.beginTx()) {
    ExecutionResult result = executionEngine.execute(query);
    // Do nifty stuff with result, then...

    // Force transaction to fail.
    ignore.failure();
}

这里的想法是,如果查询发生在事务中并且事务总是强制失败,那么无论结果如何,都不能将任何内容写入数据库。

【问题讨论】:

  • 我不知道这种可能性,但很想知道是否有办法。由于 Neo4j 2.2 引入了基本身份验证,我希望他们很快就会引入多用户和基于角色的访问,这些功能已经需要很长时间了。这不是可以轻易从外部固定的东西,我听说在他们的(内部)API 中应该相当简单。
  • 我更新了第二次编辑 - 一种可能性。不知道它有多明智。

标签: neo4j cypher


【解决方案1】:

(尚未)直接支持只读 Cypher。但是我可以想到两种解决方法:

1) 假设您正在运行 Neo4j 企业集群:您可以在一个实例上设置 read_only=true。然后将该实例用于只读查询,而其他集群实例用于读/写。可以设置集群前面的负载均衡器将请求发送到正确的实例。

2) 如果TransactionData 包含写操作,则使用TransactionEventHandler 否决事务。只是为了好玩,我已经投入了一些时间来实现它,请参阅 https://github.com/sarmbruster/read-only-cypher - 感谢您的反馈。

【讨论】:

  • 谢谢 - 我会检查这段代码。您如何看待“故意使交易失败”的做法? (在帖子中编辑 2)
  • “故意使交易失败”适用于嵌入式使用。但是,您不能使用这种方法在服务器部署中连接到 Cypher 端点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多