Skip to content

Commit e309442

Browse files
committed
fix: set transaction isolation level had no effect
The `set transaction isolation level` SQL statement was accepted by a connection, but did not actually set the isolation level.
1 parent 79bbf78 commit e309442

File tree

3 files changed

+63
-1
lines changed

3 files changed

+63
-1
lines changed

google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionImpl.java

+21
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,27 @@ public void setTransactionMode(TransactionMode transactionMode) {
859859
this.unitOfWorkType = UnitOfWorkType.of(transactionMode);
860860
}
861861

862+
IsolationLevel getTransactionIsolationLevel() {
863+
ConnectionPreconditions.checkState(!isClosed(), CLOSED_ERROR_MSG);
864+
ConnectionPreconditions.checkState(!isDdlBatchActive(), "This connection is in a DDL batch");
865+
ConnectionPreconditions.checkState(isInTransaction(), "This connection has no transaction");
866+
return this.transactionIsolationLevel;
867+
}
868+
869+
void setTransactionIsolationLevel(IsolationLevel isolationLevel) {
870+
Preconditions.checkNotNull(isolationLevel);
871+
ConnectionPreconditions.checkState(!isClosed(), CLOSED_ERROR_MSG);
872+
ConnectionPreconditions.checkState(
873+
!isBatchActive(), "Cannot set transaction isolation level while in a batch");
874+
ConnectionPreconditions.checkState(isInTransaction(), "This connection has no transaction");
875+
ConnectionPreconditions.checkState(
876+
!isTransactionStarted(),
877+
"The transaction isolation level cannot be set after the transaction has started");
878+
879+
this.transactionBeginMarked = true;
880+
this.transactionIsolationLevel = isolationLevel;
881+
}
882+
862883
@Override
863884
public String getTransactionTag() {
864885
ConnectionPreconditions.checkState(!isClosed(), CLOSED_ERROR_MSG);

google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionStatementExecutorImpl.java

+5
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,11 @@ public StatementResult statementSetTransactionMode(TransactionMode mode) {
490490

491491
@Override
492492
public StatementResult statementSetPgTransactionMode(PgTransactionMode transactionMode) {
493+
if (transactionMode.getIsolationLevel() != null) {
494+
getConnection()
495+
.setTransactionIsolationLevel(
496+
transactionMode.getIsolationLevel().getSpannerIsolationLevel());
497+
}
493498
if (transactionMode.getAccessMode() != null) {
494499
switch (transactionMode.getAccessMode()) {
495500
case READ_ONLY_TRANSACTION:

google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/TransactionMockServerTest.java

+37-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ public void testBatchDml() {
122122
}
123123

124124
@Test
125-
public void testTransactionIsolationLevel() {
125+
public void testBeginTransactionIsolationLevel() {
126126
for (Dialect dialect : new Dialect[] {Dialect.POSTGRESQL, Dialect.GOOGLE_STANDARD_SQL}) {
127127
mockSpanner.putStatementResult(
128128
MockSpannerServiceImpl.StatementResult.detectDialectResult(dialect));
@@ -158,4 +158,40 @@ public void testTransactionIsolationLevel() {
158158
SpannerPool.closeSpannerPool();
159159
}
160160
}
161+
162+
@Test
163+
public void testSetTransactionIsolationLevel() {
164+
mockSpanner.putStatementResult(
165+
MockSpannerServiceImpl.StatementResult.detectDialectResult(Dialect.POSTGRESQL));
166+
167+
try (Connection connection = createConnection()) {
168+
for (boolean autocommit : new boolean[] {true, false}) {
169+
connection.setAutocommit(autocommit);
170+
171+
for (IsolationLevel isolationLevel :
172+
new IsolationLevel[] {IsolationLevel.REPEATABLE_READ, IsolationLevel.SERIALIZABLE}) {
173+
// Manually start a transaction if autocommit is enabled.
174+
if (autocommit) {
175+
connection.execute(Statement.of("begin"));
176+
}
177+
connection.execute(
178+
Statement.of(
179+
"set transaction isolation level " + isolationLevel.name().replace("_", " ")));
180+
connection.executeUpdate(INSERT_STATEMENT);
181+
connection.commit();
182+
183+
assertEquals(1, mockSpanner.countRequestsOfType(ExecuteSqlRequest.class));
184+
ExecuteSqlRequest request = mockSpanner.getRequestsOfType(ExecuteSqlRequest.class).get(0);
185+
assertTrue(request.getTransaction().hasBegin());
186+
assertTrue(request.getTransaction().getBegin().hasReadWrite());
187+
assertEquals(isolationLevel, request.getTransaction().getBegin().getIsolationLevel());
188+
assertFalse(request.getLastStatement());
189+
assertEquals(1, mockSpanner.countRequestsOfType(CommitRequest.class));
190+
191+
mockSpanner.clearRequests();
192+
}
193+
}
194+
}
195+
SpannerPool.closeSpannerPool();
196+
}
161197
}

0 commit comments

Comments
 (0)