I am currently working on a Spring Data Neo4j 5.0.3 REST API application that interfaces with a Neo4j 3.3.1 causal cluster consisting of 3 core nodes (1 leader and 2 followers). For better or for worse, we are also submitting a lot of custom cypher queries to the database using session.query
a la SQL prepared statements. When we do this, we notice that virtually none of our custom Cypher submitted via session.query
gets sent to any of the read-only followers.
I've cracked into the code and noticed that within Neo4jSession
, the query
method always creates a transaction with type READ_WRITE
. Is there any way to get around this so that our queries get distributed across our cluster correctly?
I have also tried marking the appropriate methods with @Transactional(readOnly = true)
but it doesn't seem to work. When I did into Neo4jTransactionManager
, I see the following around line 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;
}
What does that second condition, isNewSessionHolder
, in the first branch mean? Within the context of a single HTTP API call, we call out to the database at least 2 times, so by the second query, I believe this condition always returns false.
Given these observations, are there any easy ways forward for making my queries be respected as read-only?