如何将自定义 Spring Data Neo4j 5.0.3 密码查询标记为只读
How to mark a custom Spring Data Neo4j 5.0.3 cypher query as read-only
我目前正在开发一个 Spring Data Neo4j 5.0.3 REST API 应用程序,它与由 3 个核心节点(1 个领导者和 2 个追随者)组成的 Neo4j 3.3.1 因果集群接口.无论好坏,我们还使用 session.query
a la SQL 准备好的语句向数据库提交大量自定义密码查询。当我们这样做时,我们注意到实际上 none 通过 session.query
提交的自定义 Cypher 被发送给任何只读关注者。
我破解了代码并注意到在 Neo4jSession
中,query
方法总是创建类型为 READ_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 次,因此在第二次查询中,我相信这个条件总是 returns false。
鉴于这些观察结果,是否有任何简单的方法可以使我的查询被视为只读?
关于 Spring 的第一部分:由于 Spring AOP 的限制,一个 class 中不可能有多个孤立的事务。
最好的解决方案是将调用代码与不同 classes 中的事务方法分开。然后 @Transactional(readOnly = true)
将起作用。
关于 OGM 的 session.query
调用的第二部分:如果您的工作单元参与现有的 READ_WRITE
交易,例如出现这种情况是因为上面的 @Transactional
AOP 问题,没有办法将类型设置为 READ_ONLY
。如果未设置显式类型,默认情况下 OGM 将始终创建 READ_WRITE
交易。
tl;博士;
这个问题一般有两种解决方法:
- 将
@Transactional
方法提取到另一个 class 并将调用者代码保留在现有方法中。
- 通过注入
SessionFactory
手动创建 Session
对象,并创建 READ_ONLY
类型的交易。 (并删除 @Transactional
注释)
(如 Neo4j 用户 slack 中的回答)
我目前正在开发一个 Spring Data Neo4j 5.0.3 REST API 应用程序,它与由 3 个核心节点(1 个领导者和 2 个追随者)组成的 Neo4j 3.3.1 因果集群接口.无论好坏,我们还使用 session.query
a la SQL 准备好的语句向数据库提交大量自定义密码查询。当我们这样做时,我们注意到实际上 none 通过 session.query
提交的自定义 Cypher 被发送给任何只读关注者。
我破解了代码并注意到在 Neo4jSession
中,query
方法总是创建类型为 READ_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 次,因此在第二次查询中,我相信这个条件总是 returns false。
鉴于这些观察结果,是否有任何简单的方法可以使我的查询被视为只读?
关于 Spring 的第一部分:由于 Spring AOP 的限制,一个 class 中不可能有多个孤立的事务。
最好的解决方案是将调用代码与不同 classes 中的事务方法分开。然后 @Transactional(readOnly = true)
将起作用。
关于 OGM 的 session.query
调用的第二部分:如果您的工作单元参与现有的 READ_WRITE
交易,例如出现这种情况是因为上面的 @Transactional
AOP 问题,没有办法将类型设置为 READ_ONLY
。如果未设置显式类型,默认情况下 OGM 将始终创建 READ_WRITE
交易。
tl;博士;
这个问题一般有两种解决方法:
- 将
@Transactional
方法提取到另一个 class 并将调用者代码保留在现有方法中。 - 通过注入
SessionFactory
手动创建Session
对象,并创建READ_ONLY
类型的交易。 (并删除@Transactional
注释)
(如 Neo4j 用户 slack 中的回答)