You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by GitBox <gi...@apache.org> on 2018/10/25 02:53:03 UTC

[GitHub] zhfeng closed pull request #322: [SCB-962] Support ForwardPolicy to configure the maximum of retries

zhfeng closed pull request #322: [SCB-962] Support ForwardPolicy to configure the maximum of retries
URL: https://github.com/apache/incubator-servicecomb-saga/pull/322
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/docs/api/api.md b/docs/api/api.md
index 581ab23c..756a75c0 100755
--- a/docs/api/api.md
+++ b/docs/api/api.md
@@ -21,6 +21,7 @@ POST /requests
       "transaction": {
         "method": "",
         "path": "",
+        "retries": "",
         "params": {
 
         }
@@ -28,6 +29,7 @@ POST /requests
       "compensation": {
         "method": "",
         "path": "",
+        "retries": "",
         "params": {
 
         }
@@ -46,10 +48,12 @@ JSON parameters:
   - transaction - user-defined transaction that executed by the Saga.
     - method - user-defined, HTTP method.
     - path - user-defined, HTTP path.
+    - retries - int, optional, default -1. The max retry times for transaction. If this parameter is less than or equal to 0, transaction will retry infinitely.
     - params - support `form`,`json`,`body`,`query`.
   - compensation - user-defined compensation that executed by the Saga.
     - method - user-defined, HTTP method.
     - path - user-defined, HTTP path.
+    - retries - int, optional, default 3. The max retry times for compensation.
     - params - support `form`,`json`,`body`,`query`.
 
 2. Set content type to `text/plain`.
@@ -212,12 +216,14 @@ There are a `maven` example
       ],
       "transaction": {
         "sql": "",
+        "retries": "",
         "params": [
           []
         ]
       },
       "compensation": {
         "sql": "",
+        "retries": "",
         "params": [
           []
         ]
@@ -235,9 +241,11 @@ JSON parameters:
   - parents - request ids. It means this request is only executed after all requests in the parents field are completed.
   - transaction - user-defined transaction that executed by the Saga.
     - sql - user-defined, forward sql.
+    - retries - int, optional, default -1. The max retry times for transaction. If this parameter is less than or equal to 0, transaction will retry infinitely.
     - params - parameters for forward sql.
   - compensation - user-defined compensation that executed by the Saga.
     - sql - user-defined, backward sql.
+    - retries - int, optional, default 3. The max retry times for compensation.
     - params - parameters for backward sql.
 
 4. Invoke `SagaExecutionComponent.run(String json)` function to execute saga.
diff --git a/saga-core-akka/src/test/java/org/apache/servicecomb/saga/core/actors/ActorBasedSagaIntegrationTest.java b/saga-core-akka/src/test/java/org/apache/servicecomb/saga/core/actors/ActorBasedSagaIntegrationTest.java
index dff600d6..de62cf2b 100644
--- a/saga-core-akka/src/test/java/org/apache/servicecomb/saga/core/actors/ActorBasedSagaIntegrationTest.java
+++ b/saga-core-akka/src/test/java/org/apache/servicecomb/saga/core/actors/ActorBasedSagaIntegrationTest.java
@@ -371,6 +371,7 @@ public void retriesFailedTransactionTillSuccess() {
 
     when(transaction2.send(request2.serviceName(), transactionResponse1))
         .thenThrow(exception).thenThrow(exception).thenReturn(transactionResponse2);
+    when(transaction2.retries()).thenReturn(-1);
 
     saga.run();
 
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/Compensation.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/Compensation.java
index a6a352b8..758ebd90 100644
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/Compensation.java
+++ b/saga-core/src/main/java/org/apache/servicecomb/saga/core/Compensation.java
@@ -52,8 +52,4 @@ public int retries() {
       return DEFAULT_RETRIES;
     }
   };
-
-  int DEFAULT_RETRIES = 3;
-
-  int retries();
 }
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/Fallback.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/Fallback.java
index 8c1068b2..7215a6b9 100644
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/Fallback.java
+++ b/saga-core/src/main/java/org/apache/servicecomb/saga/core/Fallback.java
@@ -34,6 +34,11 @@ public SagaResponse send(String address) {
     public SagaResponse send(String address, SagaResponse response) {
       return send(address);
     }
+
+    @Override
+    public int retries() {
+      return 0;
+    }
   };
 
   String type();
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/ForwardRecovery.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/ForwardRecovery.java
index 75e16ee8..8c10cc0a 100644
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/ForwardRecovery.java
+++ b/saga-core/src/main/java/org/apache/servicecomb/saga/core/ForwardRecovery.java
@@ -28,7 +28,7 @@
   @Override
   public SagaResponse apply(SagaTask task, SagaRequest request, SagaResponse parentResponse) {
     try {
-      do {
+      for(int i = 0; isRetryable(i, request.transaction()); i++) {
         try {
           return request.transaction().send(request.serviceName(), parentResponse);
         } catch (Exception e) {
@@ -40,7 +40,7 @@ public SagaResponse apply(SagaTask task, SagaRequest request, SagaResponse paren
           );
           Thread.sleep(request.failRetryDelayMilliseconds());
         }
-      } while (true);
+      }
     } catch (InterruptedException ignored) {
       log.warn("Applying {} interrupted in transaction {} of service {}",
           description(),
@@ -49,6 +49,15 @@ public SagaResponse apply(SagaTask task, SagaRequest request, SagaResponse paren
           ignored);
       throw new TransactionFailedException(ignored);
     }
+    throw new TransactionAbortedException(
+        String.format(
+            "Too many failures in transaction %s of service %s, abort the transaction!",
+            request.transaction(),
+            request.serviceName()));
+  }
+
+  private boolean isRetryable(int i, Transaction transaction) {
+    return transaction.retries() <= 0 || i <= transaction.retries();
   }
 
   @Override
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/GraphBasedSaga.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/GraphBasedSaga.java
index 69347fc1..d57dbe9f 100644
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/GraphBasedSaga.java
+++ b/saga-core/src/main/java/org/apache/servicecomb/saga/core/GraphBasedSaga.java
@@ -99,6 +99,10 @@ public void accept(SagaRequest request) {
             tasks.get(request.task()).compensate(request);
           }
         });
+      } catch (TransactionAbortedException e) {
+        response = new FailedSagaResponse(e);
+        log.error("Transaction aborted ", e);
+        break;
       }
     } while (currentTaskRunner.hasNext());
     log.info("Completed Saga");
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/Operation.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/Operation.java
index 59508656..c693dd27 100644
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/Operation.java
+++ b/saga-core/src/main/java/org/apache/servicecomb/saga/core/Operation.java
@@ -19,6 +19,7 @@
 
 public interface Operation {
 
+  int DEFAULT_RETRIES = 3;
   String TYPE_NOP = "NOP";
   String TYPE_REST = "rest";
   String TYPE_SQL = "sql";
@@ -27,4 +28,6 @@
   SagaResponse send(String address);
 
   SagaResponse send(String address, SagaResponse response);
+
+  int retries();
 }
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/RestOperation.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/RestOperation.java
index 153eb984..d961b2ef 100644
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/RestOperation.java
+++ b/saga-core/src/main/java/org/apache/servicecomb/saga/core/RestOperation.java
@@ -24,13 +24,19 @@
 
   private final String path;
   private final String method;
+  private final int retries;
   private final Map<String, Map<String, String>> params;
 
   public RestOperation(String path, String method, Map<String, Map<String, String>> params) {
+    this(path, method, DEFAULT_RETRIES, params);
+  }
+
+  public RestOperation(String path, String method, int retries, Map<String, Map<String, String>> params) {
     RestRequestChecker.checkParameters(method, params);
 
     this.path = path;
     this.method = method;
+    this.retries = retries;
     this.params = params == null? java.util.Collections.<String, Map<String, String>>emptyMap() : params;
   }
 
@@ -64,4 +70,9 @@ public SagaResponse send(String address) {
   public SagaResponse send(String address, SagaResponse response) {
     return send(address);
   }
+
+  @Override
+  public int retries() {
+    return this.retries;
+  }
 }
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SQLOperation.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/SQLOperation.java
index 0cfbf221..5e1ad831 100644
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SQLOperation.java
+++ b/saga-core/src/main/java/org/apache/servicecomb/saga/core/SQLOperation.java
@@ -23,10 +23,12 @@
 public class SQLOperation implements Operation {
 
   private final String sql;
+  private final int retries;
   private final List<List<String>> params;
 
-  public SQLOperation(String sql, List<List<String>> params) {
+  public SQLOperation(String sql, int retries, List<List<String>> params) {
     this.sql = sql;
+    this.retries = retries;
     this.params = params == null ? Collections.<List<String>>emptyList() : params;
   }
 
@@ -55,4 +57,9 @@ public SagaResponse send(String datasource) {
   public SagaResponse send(String datasource, SagaResponse response) {
     return send(datasource);
   }
+
+  @Override
+  public int retries() {
+    return this.retries;
+  }
 }
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/Transaction.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/Transaction.java
index 389f8fa6..a6d4c548 100644
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/Transaction.java
+++ b/saga-core/src/main/java/org/apache/servicecomb/saga/core/Transaction.java
@@ -20,6 +20,11 @@
 public interface Transaction extends Operation {
 
   Transaction SAGA_START_TRANSACTION = new Transaction() {
+    @Override
+    public int retries() {
+      return INFINITE_RETRY;
+    }
+
     @Override
     public SagaResponse send(String address) {
       return SUCCESSFUL_SAGA_RESPONSE;
@@ -32,6 +37,11 @@ public SagaResponse send(String address, SagaResponse response) {
   };
 
   Transaction SAGA_END_TRANSACTION = new Transaction() {
+    @Override
+    public int retries() {
+      return INFINITE_RETRY;
+    }
+
     @Override
     public SagaResponse send(String address) {
       return SUCCESSFUL_SAGA_RESPONSE;
@@ -42,4 +52,6 @@ public SagaResponse send(String address, SagaResponse response) {
       return send(address);
     }
   };
+
+  int INFINITE_RETRY = -1;
 }
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionAbortedException.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionAbortedException.java
new file mode 100644
index 00000000..02cbf984
--- /dev/null
+++ b/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionAbortedException.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.saga.core;
+
+public class TransactionAbortedException extends RuntimeException{
+    public TransactionAbortedException(Throwable throwable) {
+        super(throwable);
+    }
+
+    public TransactionAbortedException(String cause) {
+        super(cause);
+    }
+}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionTaskConsumer.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionTaskConsumer.java
index af2dc742..ac470a03 100644
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionTaskConsumer.java
+++ b/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionTaskConsumer.java
@@ -72,6 +72,9 @@ public void consume(Collection<Node<SagaRequest>> nodes) {
         if (e.getCause() instanceof SagaStartFailedException) {
           throw ((SagaStartFailedException) e.getCause());
         }
+        if (e.getCause() instanceof TransactionAbortedException) {
+          throw ((TransactionAbortedException) e.getCause());
+        }
         throw new TransactionFailedException(e.getCause());
       } catch (InterruptedException e) {
         // TODO: 7/29/2017 what shall we do when system is shutting down?
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/ForwardRecoveryTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/ForwardRecoveryTest.java
index 078f9966..1d21914e 100644
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/ForwardRecoveryTest.java
+++ b/saga-core/src/test/java/org/apache/servicecomb/saga/core/ForwardRecoveryTest.java
@@ -17,6 +17,9 @@
 
 package org.apache.servicecomb.saga.core;
 
+import static com.seanyinx.github.unit.scaffolding.AssertUtils.expectFailing;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
@@ -31,6 +34,7 @@
   private final SagaTask sagaTask = mock(SagaTask.class);
 
   private final Transaction transaction = mock(Transaction.class);
+
   private final SagaRequest sagaRequest = mock(SagaRequest.class);
   private final SagaResponse parentResponse = mock(SagaResponse.class);
 
@@ -38,11 +42,15 @@
 
   private final String serviceName = "aaa";
 
+  private final int numberOfRetries = 3;
+
   @Before
   public void setUp() {
     when(sagaRequest.serviceName()).thenReturn(serviceName);
     when(sagaRequest.transaction()).thenReturn(transaction);
     when(sagaRequest.failRetryDelayMilliseconds()).thenReturn(300);
+    when(transaction.retries()).thenReturn(numberOfRetries);
+    when(transaction.toString()).thenReturn(serviceName);
   }
 
   @Test
@@ -61,4 +69,18 @@ public void run() {
 
     verify(transaction, times(2)).send(serviceName, parentResponse);
   }
+
+  @Test
+  public void retriesTransportForSpecifiedTimes() {
+    doThrow(Exception.class).when(transaction).send(serviceName, parentResponse);
+
+    try {
+      forwardRecovery.apply(sagaTask, sagaRequest, parentResponse);
+      expectFailing(TransactionFailedException.class);
+    } catch (TransactionAbortedException e) {
+      assertThat(e.getMessage(), is("Too many failures in transaction aaa of service aaa, abort the transaction!"));
+    }
+
+    verify(transaction, times(4)).send(serviceName, parentResponse);
+  }
 }
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/SagaIntegrationTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/SagaIntegrationTest.java
index 19f98022..64187ebb 100644
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/SagaIntegrationTest.java
+++ b/saga-core/src/test/java/org/apache/servicecomb/saga/core/SagaIntegrationTest.java
@@ -53,6 +53,7 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.CyclicBarrier;
 
+import org.hamcrest.core.Is;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.invocation.InvocationOnMock;
@@ -371,6 +372,7 @@ public void retriesFailedTransactionTillSuccess() {
     RequestProcessTask processTask = requestProcessTask(new ForwardRecovery());
     tasks.put(SAGA_REQUEST_TASK, processTask);
 
+    when(transaction2.retries()).thenReturn(-1);
     when(transaction2.send(request2.serviceName(), transactionResponse1))
         .thenThrow(exception).thenThrow(exception).thenReturn(transactionResponse2);
 
@@ -392,6 +394,36 @@ public void retriesFailedTransactionTillSuccess() {
     verify(compensation2, never()).send(anyString(), any(SagaResponse.class));
   }
 
+  @Test
+  public void retriesFailedTransactionTillMaximum() {
+    RequestProcessTask processTask = requestProcessTask(new ForwardRecovery());
+    tasks.put(SAGA_REQUEST_TASK, processTask);
+
+    when(transaction2.send(request2.serviceName(), transactionResponse1)).thenThrow(exception);
+    when(transaction2.retries()).thenReturn(2);
+    when(transaction2.toString()).thenReturn("transaction2");
+
+    try {
+      saga.run();
+    } catch (TransactionAbortedException e) {
+      assertThat(e.getMessage(),
+          Is.is("Too many failures in transaction transaction2 of service " + request2.serviceName() + ", stop transaction!"));
+    }
+
+    assertThat(eventStore, contains(
+        eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
+        eventWith(sagaId, transaction1, TransactionStartedEvent.class),
+        eventWith(sagaId, transaction1, TransactionEndedEvent.class),
+        eventWith(sagaId, transaction2, TransactionStartedEvent.class)
+    ));
+
+    verify(transaction1).send(request1.serviceName(), EMPTY_RESPONSE);
+    verify(transaction2, times(3)).send(request2.serviceName(), transactionResponse1);
+
+    verify(compensation1, never()).send(anyString(), any(SagaResponse.class));
+    verify(compensation2, never()).send(anyString(), any(SagaResponse.class));
+  }
+
   @Test
   public void fallbackWhenCompensationFailed() {
     int retries = 3;
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/TransactionImpl.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/TransactionImpl.java
index a59b1421..b0d4a358 100644
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/TransactionImpl.java
+++ b/saga-core/src/test/java/org/apache/servicecomb/saga/core/TransactionImpl.java
@@ -24,4 +24,9 @@
   public TransactionImpl(String path, String method, Map<String, Map<String, String>> params) {
     super(path, method, params);
   }
+
+  @Override
+  public int retries() {
+    return INFINITE_RETRY;
+  }
 }
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonFallback.java b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonFallback.java
index c6cbd476..5078ceb4 100644
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonFallback.java
+++ b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonFallback.java
@@ -72,5 +72,10 @@ public SagaResponse send(String address) {
     public SagaResponse send(String address, SagaResponse response) {
       return send(address);
     }
+
+    @Override
+    public int retries() {
+      return 0;
+    }
   }
 }
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestCompensation.java b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestCompensation.java
index 1837563e..2b08edba 100644
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestCompensation.java
+++ b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestCompensation.java
@@ -26,8 +26,6 @@
 
 public class JacksonRestCompensation extends JacksonRestOperation implements Compensation {
 
-  private final int retries;
-
   public JacksonRestCompensation(
     String path,
     String method,
@@ -41,12 +39,6 @@ public JacksonRestCompensation(
       @JsonProperty("path") String path,
       @JsonProperty("method") String method,
       @JsonProperty("params") Map<String, Map<String, String>> params) {
-    super(path, method, params);
-    this.retries = retries <= 0? DEFAULT_RETRIES : retries;
-  }
-
-  @Override
-  public int retries() {
-    return retries;
+    super(path, method, retries <= 0 ? DEFAULT_RETRIES : retries, params);
   }
 }
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestFallback.java b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestFallback.java
index 92db35af..b27be0a3 100644
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestFallback.java
+++ b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestFallback.java
@@ -28,11 +28,21 @@
 
   private final String type;
 
+  public JacksonRestFallback(
+      String type,
+      String path,
+      String method,
+      Map<String, Map<String, String>> params) {
+    super(path, method, params);
+    this.type = type;
+  }
+
   @JsonCreator
   public JacksonRestFallback(
       @JsonProperty("type") String type,
       @JsonProperty("path") String path,
       @JsonProperty("method") String method,
+      @JsonProperty("retries") int retries,
       @JsonProperty("params") Map<String, Map<String, String>> params) {
     super(path, method, params);
     this.type = type;
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestOperation.java b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestOperation.java
index e9dd762a..6c90389c 100644
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestOperation.java
+++ b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestOperation.java
@@ -34,9 +34,14 @@
   private RestTransport transport;
 
   JacksonRestOperation(String path, String method, Map<String, Map<String, String>> params) {
-    super(path, method, params);
+    this(path, method, DEFAULT_RETRIES, params);
   }
 
+  JacksonRestOperation(String path, String method, int retries, Map<String, Map<String, String>> params) {
+    super(path, method, retries, params);
+  }
+
+
   @Override
   public JacksonRestOperation with(TransportFactory<RestTransport> transport) {
     this.transport = transport.getTransport();
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestTransaction.java b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestTransaction.java
index 4ea6d8c9..807ec0d7 100644
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestTransaction.java
+++ b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestTransaction.java
@@ -26,11 +26,19 @@
 
 public class JacksonRestTransaction extends JacksonRestOperation implements Transaction {
 
+  public JacksonRestTransaction(
+      String path,
+      String method,
+      Map<String, Map<String, String>> params) {
+    this(INFINITE_RETRY, path, method, params);
+  }
+
   @JsonCreator
   public JacksonRestTransaction(
+      @JsonProperty("retries") int retries,
       @JsonProperty("path") String path,
       @JsonProperty("method") String method,
       @JsonProperty("params") Map<String, Map<String, String>> params) {
-    super(path, method, params);
+    super(path, method, retries <= 0? INFINITE_RETRY : retries, params);
   }
 }
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonSQLCompensation.java b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonSQLCompensation.java
index 27e54fb4..2adf0195 100644
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonSQLCompensation.java
+++ b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonSQLCompensation.java
@@ -26,8 +26,6 @@
 
 public class JacksonSQLCompensation extends JacksonSQLOperation implements Compensation {
 
-  private final int retries;
-
   public JacksonSQLCompensation(String sql, List<List<String>> params) {
     this(sql, params, DEFAULT_RETRIES);
   }
@@ -37,12 +35,6 @@ public JacksonSQLCompensation(
       @JsonProperty("sql") String sql,
       @JsonProperty("params") List<List<String>> params,
       @JsonProperty("retries") int retries) {
-    super(sql, params);
-    this.retries = retries <= 0? DEFAULT_RETRIES : retries;
-  }
-
-  @Override
-  public int retries() {
-    return this.retries;
+    super(sql, retries <= 0? DEFAULT_RETRIES : retries, params);
   }
 }
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonSQLOperation.java b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonSQLOperation.java
index c0ac765e..8431a9b0 100644
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonSQLOperation.java
+++ b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonSQLOperation.java
@@ -32,8 +32,8 @@
   @JsonIgnore
   private SQLTransport transport;
 
-  public JacksonSQLOperation(String sql, List<List<String>> params) {
-    super(sql, params);
+  public JacksonSQLOperation(String sql, int retries, List<List<String>> params) {
+    super(sql, retries, params);
   }
 
   @Override
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonSQLTransaction.java b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonSQLTransaction.java
index a11a731c..88c69560 100644
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonSQLTransaction.java
+++ b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonSQLTransaction.java
@@ -26,10 +26,15 @@
 
 public class JacksonSQLTransaction extends JacksonSQLOperation implements Transaction {
 
+  public JacksonSQLTransaction(String sql, List<List<String>> params) {
+    this(INFINITE_RETRY, sql, params);
+  }
+
   @JsonCreator
   public JacksonSQLTransaction(
+      @JsonProperty("retries") int retries,
       @JsonProperty("sql") String sql,
       @JsonProperty("params") List<List<String>> params) {
-    super(sql, params);
+    super(sql, retries <= 0? INFINITE_RETRY : retries, params);
   }
 }
diff --git a/saga-format/src/test/java/org/apache/servicecomb/saga/format/JacksonFromJsonFormatForSQLTest.java b/saga-format/src/test/java/org/apache/servicecomb/saga/format/JacksonFromJsonFormatForSQLTest.java
index 44c22c79..a36b3604 100644
--- a/saga-format/src/test/java/org/apache/servicecomb/saga/format/JacksonFromJsonFormatForSQLTest.java
+++ b/saga-format/src/test/java/org/apache/servicecomb/saga/format/JacksonFromJsonFormatForSQLTest.java
@@ -93,10 +93,12 @@
       + "            \"parents\":[\"first-sql-sharding-1\",\"first-sql-sharding-2\"],\n"
       + "            \"transaction\":{\n"
       + "                \"sql\":\"INSERT INTO TABLE ds_1.tb_3 (id, value) values (?, ?)\",\n"
+      + "                \"retries\":5,\n"
       + "                \"params\":[[\"4\", \"xxx\"]]\n"
       + "            },\n"
       + "            \"compensation\":{\n"
       + "                \"sql\":\"DELETE FROM ds_1.tb_3 WHERE id=?\",\n"
+      + "                \"retries\":10,\n"
       + "                \"params\":[[\"4\"]]\n"
       + "            }\n"
       + "        }\n"
@@ -152,6 +154,20 @@ public String apply(SagaRequest sagaRequest) {
     }
   };
 
+  private final Function<SagaRequest, Integer> getTransactionRetries = new Function<SagaRequest, Integer>() {
+    @Override
+    public Integer apply(SagaRequest sagaRequest) {
+      return sagaRequest.transaction().retries();
+    }
+  };
+
+  private final Function<SagaRequest, Integer> getCompensationRetries = new Function<SagaRequest, Integer>() {
+    @Override
+    public Integer apply(SagaRequest sagaRequest) {
+      return sagaRequest.compensation().retries();
+    }
+  };
+
   @Test
   public void addTransportToDeserializedRequests() {
     SagaRequest[] requests = format.fromJson(requestJson).requests();
@@ -161,6 +177,8 @@ public void addTransportToDeserializedRequests() {
     assertThat(collect(requests, getRequestServiceName), contains("ds_0", "ds_0", "ds_1", "ds_1"));
     assertThat(collect(requests, getRequestType),
         contains(Operation.TYPE_SQL, Operation.TYPE_SQL, Operation.TYPE_SQL, Operation.TYPE_SQL));
+    assertThat(collect(requests, getTransactionRetries), contains(-1, -1, -1, 5));
+    assertThat(collect(requests, getCompensationRetries), contains(3, 3 ,3 ,10));
 
     SagaResponse sagaResponse = null;
 


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services