Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将自定义Spring数据Neo4j 5.0.3密码查询标记为只读_Java_Neo4j_Spring Data Neo4j_Spring Data Neo4j 5 - Fatal编程技术网

Java 如何将自定义Spring数据Neo4j 5.0.3密码查询标记为只读

Java 如何将自定义Spring数据Neo4j 5.0.3密码查询标记为只读,java,neo4j,spring-data-neo4j,spring-data-neo4j-5,Java,Neo4j,Spring Data Neo4j,Spring Data Neo4j 5,我目前正在开发一个SpringDataNeo4j5.0.3RESTAPI应用程序,该应用程序与Neo4j3.3.1因果集群接口,该集群由3个核心节点(1个领导者和2个追随者)组成。不管是好是坏,我们还使用session.querya-la-SQL-prepared语句向数据库提交大量自定义密码查询。当我们这样做时,我们注意到几乎没有一个通过session.query提交的自定义密码被发送给任何只读追随者 我破解了代码,注意到在Neo4jSession中,query方法总是创建类型为READ\u

我目前正在开发一个SpringDataNeo4j5.0.3RESTAPI应用程序,该应用程序与Neo4j3.3.1因果集群接口,该集群由3个核心节点(1个领导者和2个追随者)组成。不管是好是坏,我们还使用
session.query
a-la-SQL-prepared语句向数据库提交大量自定义密码查询。当我们这样做时,我们注意到几乎没有一个通过
session.query提交的自定义密码被发送给任何只读追随者

我破解了代码,注意到在
Neo4jSession
中,
query
方法总是创建类型为
READ\u WRITE
的事务。有没有办法绕过这一点,以便我们的查询能够正确地分布在集群中

我还尝试用
@Transactional(readOnly=true)
标记适当的方法,但似乎不起作用。当我进入
Neo4jTransactionManager
时,我在第218行看到了以下内容:

private Transaction.Type getTransactionType(TransactionDefinition definition, Neo4jTransactionObject txObject) {
    Transaction.Type type;
    if (definition.isReadOnly() && txObject.isNewSessionHolder()) {
        type = Transaction.Type.READ_ONLY;
    } else if (txObject.transactionData != null) {
        type = txObject.transactionData.type();
    } else {
        type = Transaction.Type.READ_WRITE;
    }
    return type;
}
第一个分支中的第二个条件,
isNewSessionHolder
是什么意思?在单个HTTP API调用的上下文中,我们至少调用数据库2次,因此在第二次查询中,我相信这个条件总是返回false


根据这些观察,有没有简单的方法使我的查询被视为只读的?

关于Spring的第一部分:由于Spring AOP的限制,在一个类中不可能有多个独立的事务。 最好的解决方案是将调用代码与不同类中的事务方法分开。然后,
@Transactional(readOnly=true)
将工作

关于OGM的
会话的第二部分。query
调用:如果您的工作单元参与了现有的
读写
事务,例如,这是由于上面的
@Transactional
AOP问题而发生的,则无法将类型设置为
只读
。默认情况下,如果未设置显式类型,OGM将始终创建一个
READ\u WRITE
事务

tl;博士

一般来说,有两种解决方案:

  • @Transactional
    方法提取到另一个类中,并将调用方代码保留在现有类中
  • 通过注入
    SessionFactory
    手动创建
    Session
    对象,并使用
    只读类型创建事务。(并删除
    @Transactional
    注释)

  • (如Neo4j用户松弛中所述)

    谢谢@meistermeier;我在代码中验证了我们没有受到AOP问题的影响。我们的应用程序每个HTTP请求发出2+DB呼叫(第一个是授权检查),这迫使tx管理器在第一个要读写的查询之后标记所有后续查询,因此我们最终选择了您推荐的第二个选项,它似乎达到了我们想要的效果。