|
22 | 22 | import static org.junit.Assert.assertThrows; |
23 | 23 | import static org.junit.Assert.assertTrue; |
24 | 24 |
|
| 25 | +import com.google.cloud.spanner.AbortedDueToConcurrentModificationException; |
25 | 26 | import com.google.cloud.spanner.ErrorCode; |
26 | 27 | import com.google.cloud.spanner.MockSpannerServiceImpl; |
27 | 28 | import com.google.cloud.spanner.ReadContext.QueryAnalyzeMode; |
@@ -668,4 +669,57 @@ public void testUpdateCountVerification_succeedsIfSame() { |
668 | 669 | assertEquals(5, request.getStatementsCount()); |
669 | 670 | assertEquals(1, mockSpanner.countRequestsOfType(CommitRequest.class)); |
670 | 671 | } |
| 672 | + |
| 673 | + @Test |
| 674 | + public void testTransactionRetry() { |
| 675 | + try (Connection connection = createConnection()) { |
| 676 | + assertEquals(1L, connection.executeUpdate(INSERT_STATEMENT)); |
| 677 | + assertEquals(1L, connection.executeUpdate(INSERT_STATEMENT)); |
| 678 | + try (ResultSet resultSet = connection.executeQuery(SELECT1_STATEMENT)) { |
| 679 | + assertTrue(resultSet.next()); |
| 680 | + assertEquals(1L, resultSet.getLong(0)); |
| 681 | + assertFalse(resultSet.next()); |
| 682 | + } |
| 683 | + |
| 684 | + mockSpanner.abortNextStatement(); |
| 685 | + connection.commit(); |
| 686 | + } |
| 687 | + |
| 688 | + assertEquals(2, mockSpanner.countRequestsOfType(ExecuteBatchDmlRequest.class)); |
| 689 | + ExecuteBatchDmlRequest request = |
| 690 | + mockSpanner.getRequestsOfType(ExecuteBatchDmlRequest.class).get(0); |
| 691 | + assertEquals(2, request.getStatementsCount()); |
| 692 | + assertEquals(2, mockSpanner.countRequestsOfType(ExecuteSqlRequest.class)); |
| 693 | + assertEquals(2, mockSpanner.countRequestsOfType(CommitRequest.class)); |
| 694 | + } |
| 695 | + |
| 696 | + @Test |
| 697 | + public void testTransactionRetryFails() { |
| 698 | + try (Connection connection = createConnection()) { |
| 699 | + assertEquals(1L, connection.executeUpdate(INSERT_STATEMENT)); |
| 700 | + assertEquals(1L, connection.executeUpdate(INSERT_STATEMENT)); |
| 701 | + try (ResultSet resultSet = connection.executeQuery(SELECT1_STATEMENT)) { |
| 702 | + assertTrue(resultSet.next()); |
| 703 | + assertEquals(1L, resultSet.getLong(0)); |
| 704 | + assertFalse(resultSet.next()); |
| 705 | + } |
| 706 | + |
| 707 | + // Modify the update count that is returned by the insert statement. This will cause the |
| 708 | + // retry attempt to fail. |
| 709 | + mockSpanner.putStatementResult( |
| 710 | + MockSpannerServiceImpl.StatementResult.update(INSERT_STATEMENT, 2L)); |
| 711 | + mockSpanner.abortNextStatement(); |
| 712 | + assertThrows(AbortedDueToConcurrentModificationException.class, connection::commit); |
| 713 | + } finally { |
| 714 | + mockSpanner.putStatementResult( |
| 715 | + MockSpannerServiceImpl.StatementResult.update(INSERT_STATEMENT, 1L)); |
| 716 | + } |
| 717 | + |
| 718 | + assertEquals(2, mockSpanner.countRequestsOfType(ExecuteBatchDmlRequest.class)); |
| 719 | + ExecuteBatchDmlRequest request = |
| 720 | + mockSpanner.getRequestsOfType(ExecuteBatchDmlRequest.class).get(0); |
| 721 | + assertEquals(2, request.getStatementsCount()); |
| 722 | + assertEquals(1, mockSpanner.countRequestsOfType(ExecuteSqlRequest.class)); |
| 723 | + assertEquals(1, mockSpanner.countRequestsOfType(CommitRequest.class)); |
| 724 | + } |
671 | 725 | } |
0 commit comments