Skip to content

Commit 4524f78

Browse files
committed
Support begin in read-only mode for JDBC transaction
1 parent b180847 commit 4524f78

File tree

3 files changed

+186
-96
lines changed

3 files changed

+186
-96
lines changed

core/src/integration-test/java/com/scalar/db/transaction/jdbc/JdbcTransactionIntegrationTest.java

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
import java.util.Properties;
88
import org.junit.jupiter.api.Disabled;
99
import org.junit.jupiter.api.Test;
10-
import org.junit.jupiter.params.ParameterizedTest;
11-
import org.junit.jupiter.params.provider.EnumSource;
1210

1311
public class JdbcTransactionIntegrationTest extends DistributedTransactionIntegrationTestBase {
1412

@@ -44,16 +42,4 @@ public void abort_forOngoingTransaction_ShouldAbortCorrectly() {}
4442
@Override
4543
@Test
4644
public void rollback_forOngoingTransaction_ShouldRollbackCorrectly() {}
47-
48-
@Disabled("Implement later")
49-
@Override
50-
@Test
51-
public void get_GetGivenForCommittedRecord_InReadOnlyMode_ShouldReturnRecord() {}
52-
53-
@Disabled("Implement later")
54-
@Override
55-
@ParameterizedTest
56-
@EnumSource(ScanType.class)
57-
public void scanOrGetScanner_ScanGivenForCommittedRecord_InReadOnlyMode_ShouldReturnRecords(
58-
ScanType scanType) {}
5945
}

core/src/main/java/com/scalar/db/transaction/jdbc/JdbcTransactionManager.java

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.scalar.db.api.Upsert;
1919
import com.scalar.db.common.AbstractDistributedTransactionManager;
2020
import com.scalar.db.common.AbstractTransactionManagerCrudOperableScanner;
21+
import com.scalar.db.common.ReadOnlyDistributedTransaction;
2122
import com.scalar.db.common.TableMetadataManager;
2223
import com.scalar.db.common.checker.OperationChecker;
2324
import com.scalar.db.common.error.CoreError;
@@ -36,6 +37,7 @@
3637
import com.scalar.db.storage.jdbc.RdbEngineFactory;
3738
import com.scalar.db.storage.jdbc.RdbEngineStrategy;
3839
import com.scalar.db.util.ThrowableFunction;
40+
import java.sql.Connection;
3941
import java.sql.SQLException;
4042
import java.util.List;
4143
import java.util.Optional;
@@ -90,14 +92,39 @@ public JdbcTransactionManager(DatabaseConfig databaseConfig) {
9092
@Override
9193
public DistributedTransaction begin() throws TransactionException {
9294
String txId = UUID.randomUUID().toString();
93-
return begin(txId);
95+
return begin(txId, false);
9496
}
9597

9698
@Override
9799
public DistributedTransaction begin(String txId) throws TransactionException {
100+
return begin(txId, false);
101+
}
102+
103+
@Override
104+
public DistributedTransaction beginReadOnly() throws TransactionException {
105+
String txId = UUID.randomUUID().toString();
106+
return begin(txId, true);
107+
}
108+
109+
@Override
110+
public DistributedTransaction beginReadOnly(String txId) throws TransactionException {
111+
return begin(txId, true);
112+
}
113+
114+
private DistributedTransaction begin(String txId, boolean readOnly) throws TransactionException {
98115
try {
99-
JdbcTransaction transaction =
100-
new JdbcTransaction(txId, jdbcService, dataSource.getConnection(), rdbEngine);
116+
Connection connection = dataSource.getConnection();
117+
118+
DistributedTransaction transaction;
119+
if (readOnly) {
120+
rdbEngine.setReadOnly(connection, true);
121+
transaction =
122+
new ReadOnlyDistributedTransaction(
123+
new JdbcTransaction(txId, jdbcService, connection, rdbEngine));
124+
} else {
125+
transaction = new JdbcTransaction(txId, jdbcService, connection, rdbEngine);
126+
}
127+
101128
getNamespace().ifPresent(transaction::withNamespace);
102129
getTable().ifPresent(transaction::withTable);
103130
return transaction;
@@ -109,16 +136,6 @@ public DistributedTransaction begin(String txId) throws TransactionException {
109136
}
110137
}
111138

112-
@Override
113-
public DistributedTransaction beginReadOnly() {
114-
throw new UnsupportedOperationException("implement later");
115-
}
116-
117-
@Override
118-
public DistributedTransaction beginReadOnly(String txId) {
119-
throw new UnsupportedOperationException("implement later");
120-
}
121-
122139
/** @deprecated As of release 2.4.0. Will be removed in release 4.0.0. */
123140
@SuppressWarnings("InlineMeSuggester")
124141
@Deprecated
@@ -173,19 +190,19 @@ public DistributedTransaction start(
173190

174191
@Override
175192
public Optional<Result> get(Get get) throws CrudException, UnknownTransactionStatusException {
176-
return executeTransaction(t -> t.get(copyAndSetTargetToIfNot(get)));
193+
return executeTransaction(t -> t.get(copyAndSetTargetToIfNot(get)), true);
177194
}
178195

179196
@Override
180197
public List<Result> scan(Scan scan) throws CrudException, UnknownTransactionStatusException {
181-
return executeTransaction(t -> t.scan(copyAndSetTargetToIfNot(scan)));
198+
return executeTransaction(t -> t.scan(copyAndSetTargetToIfNot(scan)), true);
182199
}
183200

184201
@Override
185202
public Scanner getScanner(Scan scan) throws CrudException {
186203
DistributedTransaction transaction;
187204
try {
188-
transaction = begin();
205+
transaction = beginReadOnly();
189206
} catch (TransactionNotFoundException e) {
190207
throw new CrudConflictException(e.getMessage(), e, e.getTransactionId().orElse(null));
191208
} catch (TransactionException e) {
@@ -277,7 +294,8 @@ public void put(Put put) throws CrudException, UnknownTransactionStatusException
277294
t -> {
278295
t.put(copyAndSetTargetToIfNot(put));
279296
return null;
280-
});
297+
},
298+
false);
281299
}
282300

283301
/** @deprecated As of release 3.13.0. Will be removed in release 5.0.0. */
@@ -288,7 +306,8 @@ public void put(List<Put> puts) throws CrudException, UnknownTransactionStatusEx
288306
t -> {
289307
t.put(copyAndSetTargetToIfNot(puts));
290308
return null;
291-
});
309+
},
310+
false);
292311
}
293312

294313
@Override
@@ -297,7 +316,8 @@ public void insert(Insert insert) throws CrudException, UnknownTransactionStatus
297316
t -> {
298317
t.insert(copyAndSetTargetToIfNot(insert));
299318
return null;
300-
});
319+
},
320+
false);
301321
}
302322

303323
@Override
@@ -306,7 +326,8 @@ public void upsert(Upsert upsert) throws CrudException, UnknownTransactionStatus
306326
t -> {
307327
t.upsert(copyAndSetTargetToIfNot(upsert));
308328
return null;
309-
});
329+
},
330+
false);
310331
}
311332

312333
@Override
@@ -315,7 +336,8 @@ public void update(Update update) throws CrudException, UnknownTransactionStatus
315336
t -> {
316337
t.update(copyAndSetTargetToIfNot(update));
317338
return null;
318-
});
339+
},
340+
false);
319341
}
320342

321343
@Override
@@ -324,7 +346,8 @@ public void delete(Delete delete) throws CrudException, UnknownTransactionStatus
324346
t -> {
325347
t.delete(copyAndSetTargetToIfNot(delete));
326348
return null;
327-
});
349+
},
350+
false);
328351
}
329352

330353
/** @deprecated As of release 3.13.0. Will be removed in release 5.0.0. */
@@ -335,7 +358,8 @@ public void delete(List<Delete> deletes) throws CrudException, UnknownTransactio
335358
t -> {
336359
t.delete(copyAndSetTargetToIfNot(deletes));
337360
return null;
338-
});
361+
},
362+
false);
339363
}
340364

341365
@Override
@@ -345,15 +369,21 @@ public void mutate(List<? extends Mutation> mutations)
345369
t -> {
346370
t.mutate(copyAndSetTargetToIfNot(mutations));
347371
return null;
348-
});
372+
},
373+
false);
349374
}
350375

351376
private <R> R executeTransaction(
352-
ThrowableFunction<DistributedTransaction, R, TransactionException> throwableFunction)
377+
ThrowableFunction<DistributedTransaction, R, TransactionException> throwableFunction,
378+
boolean readOnly)
353379
throws CrudException, UnknownTransactionStatusException {
354380
DistributedTransaction transaction;
355381
try {
356-
transaction = begin();
382+
if (readOnly) {
383+
transaction = beginReadOnly();
384+
} else {
385+
transaction = begin();
386+
}
357387
} catch (TransactionNotFoundException e) {
358388
throw new CrudConflictException(e.getMessage(), e, e.getTransactionId().orElse(null));
359389
} catch (TransactionException e) {

0 commit comments

Comments
 (0)