@@ -285,6 +285,7 @@ static UnitOfWorkType of(TransactionMode transactionMode) {
285
285
286
286
// The following properties are not 'normal' connection properties, but transient properties that
287
287
// are automatically reset after executing a transaction or statement.
288
+ private IsolationLevel transactionIsolationLevel ;
288
289
private String transactionTag ;
289
290
private String statementTag ;
290
291
private boolean excludeTxnFromChangeStreams ;
@@ -336,7 +337,7 @@ && getDialect() == Dialect.POSTGRESQL
336
337
: Type .NON_TRANSACTIONAL ));
337
338
338
339
// (Re)set the state of the connection to the default.
339
- setDefaultTransactionOptions ();
340
+ setDefaultTransactionOptions (getDefaultIsolationLevel () );
340
341
}
341
342
342
343
/** Constructor only for test purposes. */
@@ -370,7 +371,7 @@ && getDialect() == Dialect.POSTGRESQL
370
371
setReadOnly (options .isReadOnly ());
371
372
setAutocommit (options .isAutocommit ());
372
373
setReturnCommitStats (options .isReturnCommitStats ());
373
- setDefaultTransactionOptions ();
374
+ setDefaultTransactionOptions (getDefaultIsolationLevel () );
374
375
}
375
376
376
377
@ Override
@@ -505,7 +506,7 @@ private void reset(Context context, boolean inTransaction) {
505
506
this .protoDescriptorsFilePath = null ;
506
507
507
508
if (!isTransactionStarted ()) {
508
- setDefaultTransactionOptions ();
509
+ setDefaultTransactionOptions (getDefaultIsolationLevel () );
509
510
}
510
511
}
511
512
@@ -595,7 +596,7 @@ public void setAutocommit(boolean autocommit) {
595
596
// middle of a transaction.
596
597
this .connectionState .commit ();
597
598
}
598
- clearLastTransactionAndSetDefaultTransactionOptions ();
599
+ clearLastTransactionAndSetDefaultTransactionOptions (getDefaultIsolationLevel () );
599
600
// Reset the readOnlyStaleness value if it is no longer compatible with the new autocommit
600
601
// value.
601
602
if (!autocommit ) {
@@ -629,7 +630,7 @@ public void setReadOnly(boolean readOnly) {
629
630
ConnectionPreconditions .checkState (
630
631
!transactionBeginMarked , "Cannot set read-only when a transaction has begun" );
631
632
setConnectionPropertyValue (READONLY , readOnly );
632
- clearLastTransactionAndSetDefaultTransactionOptions ();
633
+ clearLastTransactionAndSetDefaultTransactionOptions (getDefaultIsolationLevel () );
633
634
}
634
635
635
636
@ Override
@@ -647,7 +648,7 @@ public void setDefaultIsolationLevel(IsolationLevel isolationLevel) {
647
648
!isTransactionStarted (),
648
649
"Cannot set default isolation level while a transaction is active" );
649
650
setConnectionPropertyValue (DEFAULT_ISOLATION_LEVEL , isolationLevel );
650
- clearLastTransactionAndSetDefaultTransactionOptions ();
651
+ clearLastTransactionAndSetDefaultTransactionOptions (isolationLevel );
651
652
}
652
653
653
654
@ Override
@@ -656,8 +657,8 @@ public IsolationLevel getDefaultIsolationLevel() {
656
657
return getConnectionPropertyValue (DEFAULT_ISOLATION_LEVEL );
657
658
}
658
659
659
- private void clearLastTransactionAndSetDefaultTransactionOptions () {
660
- setDefaultTransactionOptions ();
660
+ private void clearLastTransactionAndSetDefaultTransactionOptions (IsolationLevel isolationLevel ) {
661
+ setDefaultTransactionOptions (isolationLevel );
661
662
this .currentUnitOfWork = null ;
662
663
}
663
664
@@ -1139,13 +1140,14 @@ public boolean isKeepTransactionAlive() {
1139
1140
}
1140
1141
1141
1142
/** Resets this connection to its default transaction options. */
1142
- private void setDefaultTransactionOptions () {
1143
+ private void setDefaultTransactionOptions (IsolationLevel isolationLevel ) {
1143
1144
if (transactionStack .isEmpty ()) {
1144
1145
unitOfWorkType =
1145
1146
isReadOnly ()
1146
1147
? UnitOfWorkType .READ_ONLY_TRANSACTION
1147
1148
: UnitOfWorkType .READ_WRITE_TRANSACTION ;
1148
1149
batchMode = BatchMode .NONE ;
1150
+ transactionIsolationLevel = isolationLevel ;
1149
1151
transactionTag = null ;
1150
1152
excludeTxnFromChangeStreams = false ;
1151
1153
} else {
@@ -1155,11 +1157,21 @@ private void setDefaultTransactionOptions() {
1155
1157
1156
1158
@ Override
1157
1159
public void beginTransaction () {
1158
- get (beginTransactionAsync ());
1160
+ get (beginTransactionAsync (getConnectionPropertyValue (DEFAULT_ISOLATION_LEVEL )));
1161
+ }
1162
+
1163
+ @ Override
1164
+ public void beginTransaction (IsolationLevel isolationLevel ) {
1165
+ get (beginTransactionAsync (isolationLevel ));
1159
1166
}
1160
1167
1161
1168
@ Override
1162
1169
public ApiFuture <Void > beginTransactionAsync () {
1170
+ return beginTransactionAsync (getConnectionPropertyValue (DEFAULT_ISOLATION_LEVEL ));
1171
+ }
1172
+
1173
+ @ Override
1174
+ public ApiFuture <Void > beginTransactionAsync (IsolationLevel isolationLevel ) {
1163
1175
ConnectionPreconditions .checkState (!isClosed (), CLOSED_ERROR_MSG );
1164
1176
ConnectionPreconditions .checkState (
1165
1177
!isBatchActive (), "This connection has an active batch and cannot begin a transaction" );
@@ -1169,7 +1181,7 @@ public ApiFuture<Void> beginTransactionAsync() {
1169
1181
ConnectionPreconditions .checkState (!transactionBeginMarked , "A transaction has already begun" );
1170
1182
1171
1183
transactionBeginMarked = true ;
1172
- clearLastTransactionAndSetDefaultTransactionOptions ();
1184
+ clearLastTransactionAndSetDefaultTransactionOptions (isolationLevel );
1173
1185
if (isAutocommit ()) {
1174
1186
inTransaction = true ;
1175
1187
}
@@ -1284,7 +1296,7 @@ private ApiFuture<Void> endCurrentTransactionAsync(
1284
1296
if (isAutocommit ()) {
1285
1297
inTransaction = false ;
1286
1298
}
1287
- setDefaultTransactionOptions ();
1299
+ setDefaultTransactionOptions (getDefaultIsolationLevel () );
1288
1300
}
1289
1301
return res ;
1290
1302
}
@@ -2196,7 +2208,7 @@ UnitOfWork createNewUnitOfWork(
2196
2208
.build ();
2197
2209
if (!isInternalMetadataQuery && !forceSingleUse ) {
2198
2210
// Reset the transaction options after starting a single-use transaction.
2199
- setDefaultTransactionOptions ();
2211
+ setDefaultTransactionOptions (getDefaultIsolationLevel () );
2200
2212
}
2201
2213
return singleUseTransaction ;
2202
2214
} else {
@@ -2217,7 +2229,7 @@ UnitOfWork createNewUnitOfWork(
2217
2229
.setUsesEmulator (options .usesEmulator ())
2218
2230
.setUseAutoSavepointsForEmulator (options .useAutoSavepointsForEmulator ())
2219
2231
.setDatabaseClient (dbClient )
2220
- .setIsolationLevel (getConnectionPropertyValue ( DEFAULT_ISOLATION_LEVEL ) )
2232
+ .setIsolationLevel (transactionIsolationLevel )
2221
2233
.setDelayTransactionStartUntilFirstWrite (
2222
2234
getConnectionPropertyValue (DELAY_TRANSACTION_START_UNTIL_FIRST_WRITE ))
2223
2235
.setKeepTransactionAlive (getConnectionPropertyValue (KEEP_TRANSACTION_ALIVE ))
@@ -2401,7 +2413,7 @@ public ApiFuture<long[]> runBatchAsync() {
2401
2413
this .protoDescriptorsFilePath = null ;
2402
2414
}
2403
2415
this .batchMode = BatchMode .NONE ;
2404
- setDefaultTransactionOptions ();
2416
+ setDefaultTransactionOptions (getDefaultIsolationLevel () );
2405
2417
}
2406
2418
}
2407
2419
@@ -2415,7 +2427,7 @@ public void abortBatch() {
2415
2427
}
2416
2428
} finally {
2417
2429
this .batchMode = BatchMode .NONE ;
2418
- setDefaultTransactionOptions ();
2430
+ setDefaultTransactionOptions (getDefaultIsolationLevel () );
2419
2431
}
2420
2432
}
2421
2433
0 commit comments