Java 如何将自定义Spring数据Neo4j 5.0.3密码查询标记为只读
我目前正在开发一个SpringDataNeo4j5.0.3RESTAPI应用程序,该应用程序与Neo4j3.3.1因果集群接口,该集群由3个核心节点(1个领导者和2个追随者)组成。不管是好是坏,我们还使用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
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管理器在第一个要读写的查询之后标记所有后续查询,因此我们最终选择了您推荐的第二个选项,它似乎达到了我们想要的效果。