|
27 | 27 | import static org.junit.Assert.assertEquals;
|
28 | 28 | import static org.junit.Assert.assertNotNull;
|
29 | 29 | import static org.junit.Assert.assertThrows;
|
| 30 | +import static org.junit.Assert.assertTrue; |
30 | 31 |
|
31 | 32 | import com.google.api.core.ApiFuture;
|
32 | 33 | import com.google.api.core.ApiFutureCallback;
|
@@ -1084,6 +1085,37 @@ public void onSuccess(Long aLong) {
|
1084 | 1085 | }
|
1085 | 1086 | }
|
1086 | 1087 |
|
| 1088 | + @Test |
| 1089 | + public void testAbandonedAsyncTransactionManager_rollbackFails() throws Exception { |
| 1090 | + mockSpanner.setRollbackExecutionTime( |
| 1091 | + SimulatedExecutionTime.ofException(Status.PERMISSION_DENIED.asRuntimeException())); |
| 1092 | + |
| 1093 | + boolean gotException = false; |
| 1094 | + try (AsyncTransactionManager manager = client().transactionManagerAsync()) { |
| 1095 | + TransactionContextFuture transactionContextFuture = manager.beginAsync(); |
| 1096 | + while (true) { |
| 1097 | + try { |
| 1098 | + AsyncTransactionStep<Void, Long> updateCount = |
| 1099 | + transactionContextFuture.then( |
| 1100 | + (transactionContext, ignored) -> |
| 1101 | + transactionContext.executeUpdateAsync(UPDATE_STATEMENT), |
| 1102 | + executor); |
| 1103 | + assertEquals(1L, updateCount.get().longValue()); |
| 1104 | + // Break without committing or rolling back the transaction. |
| 1105 | + break; |
| 1106 | + } catch (AbortedException e) { |
| 1107 | + transactionContextFuture = manager.resetForRetryAsync(); |
| 1108 | + } |
| 1109 | + } |
| 1110 | + } catch (SpannerException spannerException) { |
| 1111 | + // The error from the automatically executed Rollback is surfaced when the |
| 1112 | + // AsyncTransactionManager is closed. |
| 1113 | + assertEquals(ErrorCode.PERMISSION_DENIED, spannerException.getErrorCode()); |
| 1114 | + gotException = true; |
| 1115 | + } |
| 1116 | + assertTrue(gotException); |
| 1117 | + } |
| 1118 | + |
1087 | 1119 | private boolean isMultiplexedSessionsEnabled() {
|
1088 | 1120 | if (spanner.getOptions() == null || spanner.getOptions().getSessionPoolOptions() == null) {
|
1089 | 1121 | return false;
|
|
0 commit comments