From 4926da245fbe133a6bab043e9e75258efaaeb21a Mon Sep 17 00:00:00 2001 From: Dmitriy Tverdiakov <11927660+injectives@users.noreply.github.com> Date: Thu, 7 Mar 2024 10:27:21 +0000 Subject: [PATCH] fix: Propagate the `readOnly` property to the Bolt transaction. (#544) This update makes sure that the connection's `readOnly` property is used when beginning a new Bolt transaction. --- .../java/org/neo4j/jdbc/ConnectionImpl.java | 6 +++++- .../org/neo4j/jdbc/ConnectionImplTests.java | 20 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/neo4j-jdbc/src/main/java/org/neo4j/jdbc/ConnectionImpl.java b/neo4j-jdbc/src/main/java/org/neo4j/jdbc/ConnectionImpl.java index 24d8fd63..4937e894 100644 --- a/neo4j-jdbc/src/main/java/org/neo4j/jdbc/ConnectionImpl.java +++ b/neo4j-jdbc/src/main/java/org/neo4j/jdbc/ConnectionImpl.java @@ -640,7 +640,7 @@ Neo4jTransaction getTransaction(boolean autoCommitCheck) throws SQLException { && Neo4jTransaction.State.FAILED.equals(this.transaction.getState())) ? this.boltConnection.reset(false) : CompletableFuture.completedStage(null); var transactionType = this.autoCommit ? TransactionType.UNCONSTRAINED : TransactionType.DEFAULT; - var beginStage = this.boltConnection.beginTransaction(Collections.emptySet(), AccessMode.WRITE, + var beginStage = this.boltConnection.beginTransaction(Collections.emptySet(), getAccessMode(), transactionType, false); this.transaction = new DefaultTransactionImpl(this.boltConnection, exception -> this.fatalException = exception, resetStage.thenCompose(ignored -> beginStage), @@ -649,6 +649,10 @@ Neo4jTransaction getTransaction(boolean autoCommitCheck) throws SQLException { return this.transaction; } + private AccessMode getAccessMode() { + return this.readOnly ? AccessMode.READ : AccessMode.WRITE; + } + @Override public void flushTranslationCache() { synchronized (this) { diff --git a/neo4j-jdbc/src/test/java/org/neo4j/jdbc/ConnectionImplTests.java b/neo4j-jdbc/src/test/java/org/neo4j/jdbc/ConnectionImplTests.java index be5a84fa..17695f51 100644 --- a/neo4j-jdbc/src/test/java/org/neo4j/jdbc/ConnectionImplTests.java +++ b/neo4j-jdbc/src/test/java/org/neo4j/jdbc/ConnectionImplTests.java @@ -301,6 +301,26 @@ void shouldUpdateReadOnly() throws SQLException { assertThat(connection.isReadOnly()).isTrue(); } + @ParameterizedTest + @ValueSource(booleans = { true, false }) + void shouldPassAccessModeToBoltConnection(boolean readOnly) throws SQLException { + // given + var boltConnection = mock(BoltConnection.class); + var accessMode = readOnly ? AccessMode.READ : AccessMode.WRITE; + given(boltConnection.beginTransaction(Collections.emptySet(), accessMode, TransactionType.UNCONSTRAINED, false)) + .willReturn(CompletableFuture.completedStage(null)); + var connection = makeConnection(boltConnection); + connection.setReadOnly(readOnly); + + // when + var transaction = connection.getTransaction(); + + // then + assertThat(transaction).isNotNull(); + then(boltConnection).should() + .beginTransaction(Collections.emptySet(), accessMode, TransactionType.UNCONSTRAINED, false); + } + @Test void shouldThrowOnUpdatingReadOnlyDuringTransaction() throws SQLException { var boltConnection = mock(BoltConnection.class);