1818import com .scalar .db .api .Upsert ;
1919import com .scalar .db .common .AbstractDistributedTransactionManager ;
2020import com .scalar .db .common .AbstractTransactionManagerCrudOperableScanner ;
21+ import com .scalar .db .common .ReadOnlyDistributedTransaction ;
2122import com .scalar .db .common .TableMetadataManager ;
2223import com .scalar .db .common .checker .OperationChecker ;
2324import com .scalar .db .common .error .CoreError ;
3637import com .scalar .db .storage .jdbc .RdbEngineFactory ;
3738import com .scalar .db .storage .jdbc .RdbEngineStrategy ;
3839import com .scalar .db .util .ThrowableFunction ;
40+ import java .sql .Connection ;
3941import java .sql .SQLException ;
4042import java .util .List ;
4143import 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 .setConnectionToReadOnly (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