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