@@ -257,6 +257,130 @@ public Long run(TransactionContext transaction) throws Exception {
257
257
assertThat (countTransactionsStarted ()).isEqualTo (2 );
258
258
}
259
259
260
+ @ Test
261
+ public void testInlinedBeginFirstUpdateAborts () {
262
+ DatabaseClient client = spanner .getDatabaseClient (DatabaseId .of ("p" , "i" , "d" ));
263
+ long updateCount =
264
+ client
265
+ .readWriteTransaction ()
266
+ .run (
267
+ new TransactionCallable <Long >() {
268
+ boolean firstAttempt = true ;
269
+
270
+ @ Override
271
+ public Long run (TransactionContext transaction ) throws Exception {
272
+ if (firstAttempt ) {
273
+ firstAttempt = false ;
274
+ mockSpanner .putStatementResult (
275
+ StatementResult .exception (
276
+ UPDATE_STATEMENT ,
277
+ mockSpanner .createAbortedException (
278
+ ByteString .copyFromUtf8 ("some-tx" ))));
279
+ } else {
280
+ mockSpanner .putStatementResult (
281
+ StatementResult .update (UPDATE_STATEMENT , UPDATE_COUNT ));
282
+ }
283
+ return transaction .executeUpdate (UPDATE_STATEMENT );
284
+ }
285
+ });
286
+ assertThat (updateCount ).isEqualTo (UPDATE_COUNT );
287
+ assertThat (countRequests (BeginTransactionRequest .class )).isEqualTo (1 );
288
+ assertThat (countRequests (ExecuteSqlRequest .class )).isEqualTo (2 );
289
+ assertThat (countRequests (CommitRequest .class )).isEqualTo (1 );
290
+ }
291
+
292
+ @ Test
293
+ public void testInlinedBeginFirstQueryAborts () {
294
+ DatabaseClient client = spanner .getDatabaseClient (DatabaseId .of ("p" , "i" , "d" ));
295
+ long updateCount =
296
+ client
297
+ .readWriteTransaction ()
298
+ .run (
299
+ new TransactionCallable <Long >() {
300
+ boolean firstAttempt = true ;
301
+
302
+ @ Override
303
+ public Long run (TransactionContext transaction ) throws Exception {
304
+ if (firstAttempt ) {
305
+ firstAttempt = false ;
306
+ mockSpanner .putStatementResult (
307
+ StatementResult .exception (
308
+ SELECT1 ,
309
+ mockSpanner .createAbortedException (
310
+ ByteString .copyFromUtf8 ("some-tx" ))));
311
+ } else {
312
+ mockSpanner .putStatementResult (
313
+ StatementResult .query (SELECT1 , SELECT1_RESULTSET ));
314
+ }
315
+ try (ResultSet rs = transaction .executeQuery (SELECT1 )) {
316
+ while (rs .next ()) {
317
+ return rs .getLong (0 );
318
+ }
319
+ }
320
+ return 0L ;
321
+ }
322
+ });
323
+ assertThat (updateCount ).isEqualTo (1L );
324
+ assertThat (countRequests (BeginTransactionRequest .class )).isEqualTo (1 );
325
+ assertThat (countRequests (ExecuteSqlRequest .class )).isEqualTo (2 );
326
+ assertThat (countRequests (CommitRequest .class )).isEqualTo (1 );
327
+ }
328
+
329
+ @ Test
330
+ public void testInlinedBeginFirstQueryReturnsUnavailable () {
331
+ DatabaseClient client = spanner .getDatabaseClient (DatabaseId .of ("p" , "i" , "d" ));
332
+ mockSpanner .setExecuteStreamingSqlExecutionTime (
333
+ SimulatedExecutionTime .ofStreamException (Status .UNAVAILABLE .asRuntimeException (), 0 ));
334
+ long value =
335
+ client
336
+ .readWriteTransaction ()
337
+ .run (
338
+ new TransactionCallable <Long >() {
339
+ @ Override
340
+ public Long run (TransactionContext transaction ) throws Exception {
341
+ // The first attempt will return UNAVAILABLE and retry internally.
342
+ try (ResultSet rs = transaction .executeQuery (SELECT1 )) {
343
+ while (rs .next ()) {
344
+ return rs .getLong (0 );
345
+ }
346
+ }
347
+ return 0L ;
348
+ }
349
+ });
350
+ assertThat (value ).isEqualTo (1L );
351
+ assertThat (countRequests (BeginTransactionRequest .class )).isEqualTo (0 );
352
+ assertThat (countRequests (ExecuteSqlRequest .class )).isEqualTo (2 );
353
+ assertThat (countRequests (CommitRequest .class )).isEqualTo (1 );
354
+ }
355
+
356
+ @ Test
357
+ public void testInlinedBeginFirstReadReturnsUnavailable () {
358
+ DatabaseClient client = spanner .getDatabaseClient (DatabaseId .of ("p" , "i" , "d" ));
359
+ mockSpanner .setStreamingReadExecutionTime (
360
+ SimulatedExecutionTime .ofStreamException (Status .UNAVAILABLE .asRuntimeException (), 0 ));
361
+ long value =
362
+ client
363
+ .readWriteTransaction ()
364
+ .run (
365
+ new TransactionCallable <Long >() {
366
+ @ Override
367
+ public Long run (TransactionContext transaction ) throws Exception {
368
+ // The first attempt will return UNAVAILABLE and retry internally.
369
+ try (ResultSet rs =
370
+ transaction .read ("FOO" , KeySet .all (), Arrays .asList ("ID" ))) {
371
+ while (rs .next ()) {
372
+ return rs .getLong (0 );
373
+ }
374
+ }
375
+ return 0L ;
376
+ }
377
+ });
378
+ assertThat (value ).isEqualTo (1L );
379
+ assertThat (countRequests (BeginTransactionRequest .class )).isEqualTo (0 );
380
+ assertThat (countRequests (ReadRequest .class )).isEqualTo (2 );
381
+ assertThat (countRequests (CommitRequest .class )).isEqualTo (1 );
382
+ }
383
+
260
384
@ Test
261
385
public void testInlinedBeginTxWithQuery () {
262
386
DatabaseClient client =
@@ -285,8 +409,7 @@ public Long run(TransactionContext transaction) throws Exception {
285
409
286
410
@ Test
287
411
public void testInlinedBeginTxWithRead () {
288
- DatabaseClient client =
289
- spanner .getDatabaseClient (DatabaseId .of ("[PROJECT]" , "[INSTANCE]" , "[DATABASE]" ));
412
+ DatabaseClient client = spanner .getDatabaseClient (DatabaseId .of ("p" , "i" , "d" ));
290
413
long updateCount =
291
414
client
292
415
.readWriteTransaction ()
0 commit comments