Data consistency solution
This demo shows you how to use the Saga solution provided by ServiceComb to ensure the microservice for data consistency.
With microservice architecture, each of the services may have its own database technology and it’s not feasible to ensure all transactions on these services are either committed or rolled back with database. In this demo, we make use of Saga to ensure eventual data consistency among services, the payment is only executed after car rental, flight booking, and hotel-reservation are completed.
Travel application demo including four services
- flight booking service
- car rental service
- hotel reservation service
- payment service
Running Demo
Note, demo is in the ServiceComb-Saga project.
- Prerequisites
-
Configuration Set service center address of each microservice in microservice.yaml file
APPLICATION_ID: saga service_description: name: flight-booking-service version: 0.0.1 servicecomb: service: registry: address: http://sc.servicecomb.io:30100 #choose Service Center provided by ServiceComb rest: address: 0.0.0.0:8080 handler: chain: Consumer: default: loadbalance
Set deployment script in saga-demo/docker-compose.yaml file
version: '2.1' services: service-center: #choose Service Center image provided by ServiceComb image: "servicecomb/service-center" hostname: service-center ports: - "30100:30100" mysql: #choose mysql image with 5.7 version image: "mysql/mysql-server:5.7" hostname: mysql environment: - MYSQL_ROOT_PASSWORD=password - MYSQL_DATABASE=saga - MYSQL_USER=saga - MYSQL_PASSWORD=password ports: - "3306:3306" healthcheck: test: ["CMD-SHELL", "nc -z localhost 3306 &> /dev/null; echo $$?"] interval: 30s timeout: 10s retries: 5 car-rental-service: image: "car-rental-service:0.0.2-SNAPSHOT" hostname: car links: - "service-center:sc.servicecomb.io" ports: - "8080:8080" flight-booking-service: image: "flight-booking-service:0.0.2-SNAPSHOT" hostname: flight links: - "service-center:sc.servicecomb.io" ports: - "8081:8080" hotel-reservation-service: image: "hotel-reservation-service:0.0.2-SNAPSHOT" hostname: hotel links: - "service-center:sc.servicecomb.io" ports: - "8082:8080" payment-service: image: "payment-service:0.0.2-SNAPSHOT" hostname: payment links: - "service-center:sc.servicecomb.io" ports: - "8080" saga: image: "saga-spring:0.0.2-SNAPSHOT" hostname: saga links: - "mysql:mysql.servicecomb.io" - "service-center:sc.servicecomb.io" - "car-rental-service:car.servicecomb.io" - "flight-booking-service:flight.servicecomb.io" - "hotel-reservation-service:hotel.servicecomb.io" - "payment-service:payment.servicecomb.io" environment: - JAVA_OPTS=-Dspring.profiles.active=prd,servicecomb -Dcse.service.registry.address=http://sc.servicecomb.io:30100 ports: - "8083:8080" depends_on: mysql: condition: service_healthy
-
Run the following command to create docker images in saga project root folder
mvn package -DskipTests -Pdocker -Pdemo
-
Start application up in saga/saga-demo/ with the following command
docker-compose up
Verify services
-
Use Saga API to set request content and save it to request.json
{ "policy": "BackwardRecovery", "requests": [ { "id": "request-car", "type": "rest", "serviceName": "car-rental-service", "transaction": { "method": "post", "path": "/rentals", "params": { "form": { "customerId": "mike" } } }, "compensation": { "method": "put", "path": "/rentals", "params": { "form": { "customerId": "mike" } } } }, { "id": "request-hotel", "type": "rest", "serviceName": "hotel-reservation-service", "transaction": { "method": "post", "path": "/reservations", "params": { "form": { "customerId": "mike" } } }, "compensation": { "method": "put", "path": "/reservations", "params": { "form": { "customerId": "mike" } } } }, { "id": "request-flight", "type": "rest", "serviceName": "flight-booking-service", "transaction": { "method": "post", "path": "/bookings", "params": { "form": { "customerId": "mike" } } }, "compensation": { "method": "put", "path": "/bookings", "params": { "form": { "customerId": "mike" } } } }, { "id": "request-payment", "type": "rest", "serviceName": "payment-service", "parents": [ "request-car", "request-flight", "request-hotel" ], "transaction": { "method": "post", "path": "/payments", "params": { "form": { "customerId": "mike" } } }, "compensation": { "method": "put", "path": "/payments", "params": { "form": { "customerId": "mike" } } } } ] }
-
Set content type to text/plain, and send request.json to Saga
curl -XPOST -H "Content-Type: text/plain" -d @./request.json http://<localhost.ip:8083>/requests
Response(return “success” if execution successfully, otherwise return failed with error info)
success
-
Get all the Saga events
curl -XGET http://<localhost.ip:8083>/events
Response
{ "bcd27f0d-6b82-49b3-8067-b16eba970e55": [ { "id": 1, "sagaId": "bcd27f0d-6b82-49b3-8067-b16eba970e55", "creationTime": "2017-09-20T00:30:21Z", "type": "SagaStartedEvent", "contentJson": "{\"policy\": \"BackwardRecovery\", \"requests\": [{\"id\": \"request-car\", \"type\": \"rest\", \"serviceName\": \"car-rental-service\", \"transaction\": {\"path\": \"/rentals\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/rentals\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}}, {\"id\": \"request-hotel\", \"type\": \"rest\", \"serviceName\": \"hotel-reservation-service\", \"transaction\": {\"path\": \"/reservations\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/reservations\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}}, {\"id\": \"request-flight\", \"type\": \"rest\", \"serviceName\": \"flight-booking-service\", \"transaction\": {\"path\": \"/bookings\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/bookings\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}}, {\"id\": \"request-payment\", \"type\": \"rest\", \"parents\": [\"request-car\", \"request-flight\", \"request-hotel\"], \"serviceName\": \"payment-service\", \"transaction\": {\"path\": \"/payments\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/payments\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}}]}" }, { "id": 2, "sagaId": "bcd27f0d-6b82-49b3-8067-b16eba970e55", "creationTime": "2017-09-20T00:30:21Z", "type": "TransactionStartedEvent", "contentJson": "{\"id\": \"request-hotel\", \"type\": \"rest\", \"parents\": [], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"hotel-reservation-service\", \"transaction\": {\"path\": \"/reservations\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/reservations\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}" }, { "id": 3, "sagaId": "bcd27f0d-6b82-49b3-8067-b16eba970e55", "creationTime": "2017-09-20T00:30:21Z", "type": "TransactionStartedEvent", "contentJson": "{\"id\": \"request-car\", \"type\": \"rest\", \"parents\": [], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"car-rental-service\", \"transaction\": {\"path\": \"/rentals\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/rentals\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}" }, { "id": 4, "sagaId": "bcd27f0d-6b82-49b3-8067-b16eba970e55", "creationTime": "2017-09-20T00:30:21Z", "type": "TransactionStartedEvent", "contentJson": "{\"id\": \"request-flight\", \"type\": \"rest\", \"parents\": [], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"flight-booking-service\", \"transaction\": {\"path\": \"/bookings\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/bookings\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}" }, { "id": 5, "sagaId": "bcd27f0d-6b82-49b3-8067-b16eba970e55", "creationTime": "2017-09-20T00:30:22Z", "type": "TransactionEndedEvent", "contentJson": "{\"request\": {\"id\": \"request-flight\", \"type\": \"rest\", \"parents\": [], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"flight-booking-service\", \"transaction\": {\"path\": \"/bookings\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/bookings\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}, \"response\": {\"body\": \"{\\n \\\"statusCode\\\": 200,\\n \\\"content\\\": \\\"Flight booked with id f249543b-765e-4e10-9ba3-74fe33d8af83 for customer mike\\\"\\n}\"}}" }, { "id": 6, "sagaId": "bcd27f0d-6b82-49b3-8067-b16eba970e55", "creationTime": "2017-09-20T00:30:24Z", "type": "TransactionEndedEvent", "contentJson": "{\"request\": {\"id\": \"request-hotel\", \"type\": \"rest\", \"parents\": [], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"hotel-reservation-service\", \"transaction\": {\"path\": \"/reservations\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/reservations\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}, \"response\": {\"body\": \"{\\n \\\"statusCode\\\": 200,\\n \\\"content\\\": \\\"Hotel reserved with id f74049a0-3d3d-49b6-a45b-058a409daecf for customer mike\\\"\\n}\"}}" }, { "id": 7, "sagaId": "bcd27f0d-6b82-49b3-8067-b16eba970e55", "creationTime": "2017-09-20T00:30:25Z", "type": "TransactionEndedEvent", "contentJson": "{\"request\": {\"id\": \"request-car\", \"type\": \"rest\", \"parents\": [], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"car-rental-service\", \"transaction\": {\"path\": \"/rentals\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/rentals\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}, \"response\": {\"body\": \"{\\n \\\"statusCode\\\": 200,\\n \\\"content\\\": \\\"Car rented with id 937d7364-be07-4d47-9e01-af72290d0478 for customer mike\\\"\\n}\"}}" }, { "id": 8, "sagaId": "bcd27f0d-6b82-49b3-8067-b16eba970e55", "creationTime": "2017-09-20T00:30:25Z", "type": "TransactionStartedEvent", "contentJson": "{\"id\": \"request-payment\", \"type\": \"rest\", \"parents\": [\"request-car\", \"request-flight\", \"request-hotel\"], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"payment-service\", \"transaction\": {\"path\": \"/payments\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/payments\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}" }, { "id": 9, "sagaId": "bcd27f0d-6b82-49b3-8067-b16eba970e55", "creationTime": "2017-09-20T00:30:25Z", "type": "TransactionEndedEvent", "contentJson": "{\"request\": {\"id\": \"request-payment\", \"type\": \"rest\", \"parents\": [\"request-car\", \"request-flight\", \"request-hotel\"], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"payment-service\", \"transaction\": {\"path\": \"/payments\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/payments\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}, \"response\": {\"body\": \"{\\n \\\"statusCode\\\": 200,\\n \\\"content\\\": \\\"Payment made for customer mike and remaining balance is 200\\\"\\n}\"}}" }, { "id": 10, "sagaId": "bcd27f0d-6b82-49b3-8067-b16eba970e55", "creationTime": "2017-09-20T00:30:25Z", "type": "SagaEndedEvent", "contentJson": "{}" } ] }
-
Sending the request more than once will trigger compensation due to insufficient account balance in payment-service.Do this implement and get Saga events, you can find compensation events in Saga log.
{ "bcd27f0d-6b82-49b3-8067-b16eba970e55": [ ... ], "2654fa50-71e2-4fc8-afc2-6a5e0d3dafe9": [ { "id": 11, "sagaId": "2654fa50-71e2-4fc8-afc2-6a5e0d3dafe9", "creationTime": "2017-09-20T00:30:45Z", "type": "SagaStartedEvent", "contentJson": "{\"policy\": \"BackwardRecovery\", \"requests\": [{\"id\": \"request-car\", \"type\": \"rest\", \"serviceName\": \"car-rental-service\", \"transaction\": {\"path\": \"/rentals\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/rentals\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}}, {\"id\": \"request-hotel\", \"type\": \"rest\", \"serviceName\": \"hotel-reservation-service\", \"transaction\": {\"path\": \"/reservations\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/reservations\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}}, {\"id\": \"request-flight\", \"type\": \"rest\", \"serviceName\": \"flight-booking-service\", \"transaction\": {\"path\": \"/bookings\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/bookings\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}}, {\"id\": \"request-payment\", \"type\": \"rest\", \"parents\": [\"request-car\", \"request-flight\", \"request-hotel\"], \"serviceName\": \"payment-service\", \"transaction\": {\"path\": \"/payments\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/payments\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}}]}" }, { "id": 12, "sagaId": "2654fa50-71e2-4fc8-afc2-6a5e0d3dafe9", "creationTime": "2017-09-20T00:30:45Z", "type": "TransactionStartedEvent", "contentJson": "{\"id\": \"request-car\", \"type\": \"rest\", \"parents\": [], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"car-rental-service\", \"transaction\": {\"path\": \"/rentals\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/rentals\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}" }, { "id": 13, "sagaId": "2654fa50-71e2-4fc8-afc2-6a5e0d3dafe9", "creationTime": "2017-09-20T00:30:45Z", "type": "TransactionStartedEvent", "contentJson": "{\"id\": \"request-hotel\", \"type\": \"rest\", \"parents\": [], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"hotel-reservation-service\", \"transaction\": {\"path\": \"/reservations\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/reservations\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}" }, { "id": 14, "sagaId": "2654fa50-71e2-4fc8-afc2-6a5e0d3dafe9", "creationTime": "2017-09-20T00:30:45Z", "type": "TransactionStartedEvent", "contentJson": "{\"id\": \"request-flight\", \"type\": \"rest\", \"parents\": [], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"flight-booking-service\", \"transaction\": {\"path\": \"/bookings\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/bookings\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}" }, { "id": 15, "sagaId": "2654fa50-71e2-4fc8-afc2-6a5e0d3dafe9", "creationTime": "2017-09-20T00:30:45Z", "type": "TransactionEndedEvent", "contentJson": "{\"request\": {\"id\": \"request-car\", \"type\": \"rest\", \"parents\": [], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"car-rental-service\", \"transaction\": {\"path\": \"/rentals\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/rentals\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}, \"response\": {\"body\": \"{\\n \\\"statusCode\\\": 200,\\n \\\"content\\\": \\\"Car rented with id 75f4be4b-0d32-4bbb-b786-7b39c340682a for customer mike\\\"\\n}\"}}" }, { "id": 16, "sagaId": "2654fa50-71e2-4fc8-afc2-6a5e0d3dafe9", "creationTime": "2017-09-20T00:30:45Z", "type": "TransactionEndedEvent", "contentJson": "{\"request\": {\"id\": \"request-hotel\", \"type\": \"rest\", \"parents\": [], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"hotel-reservation-service\", \"transaction\": {\"path\": \"/reservations\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/reservations\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}, \"response\": {\"body\": \"{\\n \\\"statusCode\\\": 200,\\n \\\"content\\\": \\\"Hotel reserved with id 7ad11c00-25eb-4b4b-b1fb-b55d4e833f51 for customer mike\\\"\\n}\"}}" }, { "id": 17, "sagaId": "2654fa50-71e2-4fc8-afc2-6a5e0d3dafe9", "creationTime": "2017-09-20T00:30:45Z", "type": "TransactionEndedEvent", "contentJson": "{\"request\": {\"id\": \"request-flight\", \"type\": \"rest\", \"parents\": [], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"flight-booking-service\", \"transaction\": {\"path\": \"/bookings\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/bookings\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}, \"response\": {\"body\": \"{\\n \\\"statusCode\\\": 200,\\n \\\"content\\\": \\\"Flight booked with id 1a40d7bf-ee66-46d1-b066-a9973f15176a for customer mike\\\"\\n}\"}}" }, { "id": 18, "sagaId": "2654fa50-71e2-4fc8-afc2-6a5e0d3dafe9", "creationTime": "2017-09-20T00:30:45Z", "type": "TransactionStartedEvent", "contentJson": "{\"id\": \"request-payment\", \"type\": \"rest\", \"parents\": [\"request-car\", \"request-flight\", \"request-hotel\"], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"payment-service\", \"transaction\": {\"path\": \"/payments\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/payments\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}" }, { "id": 19, "sagaId": "2654fa50-71e2-4fc8-afc2-6a5e0d3dafe9", "creationTime": "2017-09-20T00:31:15Z", "type": "TransactionAbortedEvent", "contentJson": "{\"request\": {\"id\": \"request-payment\", \"type\": \"rest\", \"parents\": [\"request-car\", \"request-flight\", \"request-hotel\"], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"payment-service\", \"transaction\": {\"path\": \"/payments\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/payments\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}, \"response\": {\"body\": \"{\\n \\\"body\\\": \\\"org.apache.servicecomb.saga.core.TransactionFailedException: The remote service payment-service failed to serve the post request to /payments \\n\\tat org.apache.servicecomb.saga.discovery.service.center.ServiceCenterDiscoveryRestTransport.with(ServiceCenterDiscoveryRestTransport.java:81)\\n\\tat org.apache.servicecomb.saga.format.JacksonRestOperation.send(JacksonRestOperation.java:43)\\n\\tat org.apache.servicecomb.saga.format.JacksonRestTransaction.send(JacksonRestTransaction.java:24)\\n\\tat org.apache.servicecomb.saga.core.RequestProcessTask.commit(RequestProcessTask.java:45)\\n\\tat org.apache.servicecomb.saga.core.BackwardRecovery.apply(BackwardRecovery.java:33)\\n\\tat org.apache.servicecomb.saga.core.LoggingRecoveryPolicy.apply(LoggingRecoveryPolicy.java:38)\\n\\tat org.apache.servicecomb.saga.core.TransactionTaskConsumer$OperationCallable.call(TransactionTaskConsumer.java:110)\\n\\tat org.apache.servicecomb.saga.core.TransactionTaskConsumer$OperationCallable.call(TransactionTaskConsumer.java:94)\\n\\tat java.util.concurrent.FutureTask.run(FutureTask.java:266)\\n\\tat java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)\\n\\tat java.util.concurrent.FutureTask.run(FutureTask.java:266)\\n\\tat java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)\\n\\tat java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)\\n\\tat java.lang.Thread.run(Thread.java:748)\\nCaused by: InvocationException: code=490;msg=CommonExceptionData [message=Cse Internal Bad Request]\\n\\tat org.apache.servicecomb.swagger.invocation.exception.ExceptionFactory.doCreate(ExceptionFactory.java:74)\\n\\tat org.apache.servicecomb.swagger.invocation.exception.ExceptionFactory.convertException(ExceptionFactory.java:119)\\n\\tat org.apache.servicecomb.swagger.invocation.exception.ExceptionFactory.convertConsumerException(ExceptionFactory.java:78)\\n\\tat org.apache.servicecomb.swagger.invocation.Response.createConsumerFail(Response.java:128)\\n\\tat org.apache.servicecomb.swagger.invocation.Response.createFail(Response.java:121)\\n\\tat org.apache.servicecomb.swagger.invocation.AsyncResponse.fail(AsyncResponse.java:41)\\n\\tat org.apache.servicecomb.transport.rest.client.http.VertxHttpMethod.lambda$doMethod$0(VertxHttpMethod.java:67)\\n\\tat io.vertx.core.http.impl.HttpClientRequestBase.handleException(HttpClientRequestBase.java:110)\\n\\tat io.vertx.core.http.impl.HttpClientRequestImpl.handleException(HttpClientRequestImpl.java:50)\\n\\tat io.vertx.core.http.impl.HttpClientRequestBase.timeout(HttpClientRequestBase.java:155)\\n\\tat io.vertx.core.http.impl.HttpClientRequestBase.handleTimeout(HttpClientRequestBase.java:140)\\n\\tat io.vertx.core.http.impl.HttpClientRequestBase.lambda$setTimeout$0(HttpClientRequestBase.java:100)\\n\\tat io.vertx.core.impl.VertxImpl$InternalTimerHandler.handle(VertxImpl.java:782)\\n\\tat io.vertx.core.impl.VertxImpl$InternalTimerHandler.handle(VertxImpl.java:753)\\n\\tat io.vertx.core.impl.ContextImpl.lambda$wrapTask$2(ContextImpl.java:316)\\n\\tat io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)\\n\\tat io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:418)\\n\\tat io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:440)\\n\\tat io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:873)\\n\\t... 1 more\\nCaused by: java.util.concurrent.TimeoutException: The timeout period of 30000ms has been exceeded\\n\\t... 11 more\\n\\\"\\n}\"}}" }, { "id": 20, "sagaId": "2654fa50-71e2-4fc8-afc2-6a5e0d3dafe9", "creationTime": "2017-09-20T00:31:15Z", "type": "TransactionCompensatedEvent", "contentJson": "{\"request\": {\"id\": \"request-car\", \"type\": \"rest\", \"parents\": [], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"car-rental-service\", \"transaction\": {\"path\": \"/rentals\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/rentals\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}, \"response\": {\"body\": \"{\\n \\\"statusCode\\\": 200,\\n \\\"content\\\": \\\"Car rental cancelled with id 38bc5913-6768-4321-add3-6d26db364c19 for customer mike\\\"\\n}\"}}" }, { "id": 21, "sagaId": "2654fa50-71e2-4fc8-afc2-6a5e0d3dafe9", "creationTime": "2017-09-20T00:31:15Z", "type": "TransactionCompensatedEvent", "contentJson": "{\"request\": {\"id\": \"request-hotel\", \"type\": \"rest\", \"parents\": [], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"hotel-reservation-service\", \"transaction\": {\"path\": \"/reservations\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/reservations\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}, \"response\": {\"body\": \"{\\n \\\"statusCode\\\": 200,\\n \\\"content\\\": \\\"Hotel reservation cancelled with id efcff718-fb74-4b70-a2e2-689ecb42206d for customer mike\\\"\\n}\"}}" }, { "id": 22, "sagaId": "2654fa50-71e2-4fc8-afc2-6a5e0d3dafe9", "creationTime": "2017-09-20T00:31:15Z", "type": "TransactionCompensatedEvent", "contentJson": "{\"request\": {\"id\": \"request-flight\", \"type\": \"rest\", \"parents\": [], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"flight-booking-service\", \"transaction\": {\"path\": \"/bookings\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/bookings\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}, \"response\": {\"body\": \"{\\n \\\"statusCode\\\": 200,\\n \\\"content\\\": \\\"Flight booking cancelled with id 37572464-6f53-4351-aa37-5f88e3f1f872 for customer mike\\\"\\n}\"}}" }, { "id": 23, "sagaId": "2654fa50-71e2-4fc8-afc2-6a5e0d3dafe9", "creationTime": "2017-09-20T00:31:15Z", "type": "SagaEndedEvent", "contentJson": "{}" } ] }
What’s next
-
Learn more from Eventual Data Consistency Solution in ServiceComb - part 1
-
Learn more from Eventual Data Consistency Solution in ServiceComb - part 2
-
Learn more from Eventual Data Consistency Solution in ServiceComb - part 3