This is an automated email from the ASF dual-hosted git repository.

zhanglei pushed a commit to branch zhanglei-path-1
in repository https://gitbox.apache.org/repos/asf/servicecomb-website.git


The following commit(s) were added to refs/heads/zhanglei-path-1 by this push:
     new 41abd9f  Update package name error in the document
41abd9f is described below

commit 41abd9f85b59e3a264736ea02e10ab2b9ebbff71
Author: Lei Zhang <zhang...@apache.org>
AuthorDate: Mon Oct 21 21:16:13 2019 +0800

    Update package name error in the document
---
 _docs/cn/quick-start-dataconsistency.md    | 920 ++++++++++++++--------------
 _docs/quick-start-dataconsistency.md       | 924 ++++++++++++++---------------
 _posts/cn/2018-04-04-saga-pack-design.md   |   4 +-
 _posts/cn/2018-04-28-saga_with_cucumber.md |   4 +-
 4 files changed, 926 insertions(+), 926 deletions(-)

diff --git a/_docs/cn/quick-start-dataconsistency.md 
b/_docs/cn/quick-start-dataconsistency.md
index 8eca802..1f0e105 100755
--- a/_docs/cn/quick-start-dataconsistency.md
+++ b/_docs/cn/quick-start-dataconsistency.md
@@ -1,460 +1,460 @@
----
-title: "数据一致性解决方案"
-lang: cn
-ref: quick-start-dataconsistency
-permalink: /cn/docs/quick-start-dataconsistency/
-excerpt: "介绍ServiceComb的Saga数据一致性方案应用demo"
-last_modified_at: 2017-09-19T11:50:10-04:00
----
-
-{% include toc %}
-模拟一个简单的旅行应用,展示如何使用ServiceComb提供的Saga方案保证微服务间数据一致性。
-
-旅行应用包含四个微服务:
-- 机票预订服务(flight-booking-service)
-- 租车服务(car-rental-service)
-- 酒店预订服务(hotel-reservation-service)
-- 支付服务(payment-service)
-
-机票预订、租车、酒店预订服务间无依赖关系,使用自己的数据库,通过HTTP协议通信。
-在以上三个服务的预订成功,支付完成后才能满足一个成功的行程,否则不能成行,Saga自动补偿。
-
-![Saga-demo]({{ site.url }}{{ site.baseurl }}/assets/images/saga-demo.png)
-
-## 运行demo
-
-注:Demo 集成在 [ServiceComb-Saga](https://github.com/apache/servicecomb-saga) 项目中。
-
-1. 准备环境
-- [Oracle JDK 
1.8](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html)
-- [Maven 3.x](https://maven.apache.org/install.html)
-- [Docker](https://www.docker.com/get-docker)
-- [MySQL](https://dev.mysql.com/downloads/)
-- [Service Center](https://github.com/apache/servicecomb-service-center)
-- [Docker compose](https://docs.docker.com/compose/install/)
-
-2. 配置服务
-       在各服务的 *microservice.yaml* 文件,设置该服务注册的服务中心
-
-       ```yaml
-       APPLICATION_ID: saga
-       service_description:
-         name: flight-booking-service
-         version: 0.0.1
-       servicecomb:
-         service:
-           registry:
-             address: http://sc.servicecomb.io:30100 
#此处选择使用ServiceComb的Service Center
-         rest:
-           address: 0.0.0.0:8080
-         handler:
-           chain:
-             Consumer:
-               default: loadbalance
-       ```
-
-       在 *saga-demo/docker-compose.yaml* 设置部署脚本
-       ```yaml
-       version: '2.1'
-
-       services:
-         service-center: #此处选择使用ServiceComb的Service Center容器镜像
-           image: "servicecomb/service-center"
-           hostname: service-center
-           ports:
-             - "30100:30100"
-
-         mysql:  #此处选择使用5.7版本的mysql镜像
-           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
-       ```
-
-3. 在Saga项目的根目录执行编译,制作Saga、机票预订、租车、酒店预订和支付服务镜像
-
-       ```bash
-       mvn package -DskipTests -Pdocker -Pdemo
-       ```
-
-4. 在Saga项目的saga-demo目录通过docker-compose一键启动Saga、机票预订、租车、酒店预订和支付服务
-
-       ```bash
-       docker-compose up
-       ```
-
-## 验证
-
-1. 参照 [Saga 
API](https://github.com/apache/servicecomb-saga/blob/master/docs/api/api.md) 
说明,设定各服务的事务、补偿、依赖和恢复参数,并保存为 *request.json* 文件
-
-       ```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"
-                 }
-               }
-             }
-           }
-         ]
-       }
-       ```
-
-2. 发送请求到Saga
-
-       ```bash
-       curl -XPOST -H "Content-Type: text/plain" -d @./request.json  
http://<localhost.ip:8083>/requests
-       ```
-
-    获取处理结果成功(如果失败,返回相应的错误信息)
-       ```bash
-       success
-       ```
-
-3. 查看Saga的事务
-
-       ```bash
-       curl -XGET http://<localhost.ip:8083>/events
-       ```
-
-    查询结果
-
-       ```bash
-       {
-           "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-servic [...]
-               },
-               {
-                   "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\\\ [...]
-               },
-               {
-                   "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  \\\"sta [...]
-               },
-               {
-                   "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,\\ [...]
-               },
-               {
-                   "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}}, \" [...]
-               },
-               {
-                   "id": 10,
-                   "sagaId": "bcd27f0d-6b82-49b3-8067-b16eba970e55",
-                   "creationTime": "2017-09-20T00:30:25Z",
-                   "type": "SagaEndedEvent",
-                   "contentJson": "{}"
-               }
-       ]
-       }
-       ```
-
-4. demo中模拟了支付服务帐户余额不足场景,发送请求超过一次将触发补偿操作。再次发送请求,可以在Saga日志中找到补偿事件
-
-       ```bash
-       {
-           "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-servic [...]
-               },
-               {
-                   "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,\\ [...]
-               },
-               {
-                   "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  \\\"sta [...]
-               },
-               {
-                   "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\\\ [...]
-               },
-               {
-                   "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}}, \" [...]
-               },
-               {
-                   "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,\\ [...]
-               },
-               {
-                   "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  \\\"sta [...]
-               },
-               {
-                   "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\\\ [...]
-               },
-               {
-                   "id": 23,
-                   "sagaId": "2654fa50-71e2-4fc8-afc2-6a5e0d3dafe9",
-                   "creationTime": "2017-09-20T00:31:15Z",
-                   "type": "SagaEndedEvent",
-                   "contentJson": "{}"
-               }
-           ]
-       }
-       ```
-
-## 下一步
-
-* 了解更多[ServiceComb中的数据最终一致性方案 - part 1](/cn/docs/distributed_saga_1/)
-
-* 了解更多[ServiceComb中的数据最终一致性方案 - part 2](/cn/docs/distributed_saga_2/)
-
-* 了解更多[ServiceComb中的数据最终一致性方案 - part 3](/cn/docs/distributed_saga_3/)
+---
+title: "数据一致性解决方案"
+lang: cn
+ref: quick-start-dataconsistency
+permalink: /cn/docs/quick-start-dataconsistency/
+excerpt: "介绍ServiceComb的Saga数据一致性方案应用demo"
+last_modified_at: 2017-09-19T11:50:10-04:00
+---
+
+{% include toc %}
+模拟一个简单的旅行应用,展示如何使用ServiceComb提供的Saga方案保证微服务间数据一致性。
+
+旅行应用包含四个微服务:
+- 机票预订服务(flight-booking-service)
+- 租车服务(car-rental-service)
+- 酒店预订服务(hotel-reservation-service)
+- 支付服务(payment-service)
+
+机票预订、租车、酒店预订服务间无依赖关系,使用自己的数据库,通过HTTP协议通信。
+在以上三个服务的预订成功,支付完成后才能满足一个成功的行程,否则不能成行,Saga自动补偿。
+
+![Saga-demo]({{ site.url }}{{ site.baseurl }}/assets/images/saga-demo.png)
+
+## 运行demo
+
+注:Demo 集成在 [ServiceComb-Saga](https://github.com/apache/servicecomb-saga) 项目中。
+
+1. 准备环境
+- [Oracle JDK 
1.8](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html)
+- [Maven 3.x](https://maven.apache.org/install.html)
+- [Docker](https://www.docker.com/get-docker)
+- [MySQL](https://dev.mysql.com/downloads/)
+- [Service Center](https://github.com/apache/servicecomb-service-center)
+- [Docker compose](https://docs.docker.com/compose/install/)
+
+2. 配置服务
+       在各服务的 *microservice.yaml* 文件,设置该服务注册的服务中心
+
+       ```yaml
+       APPLICATION_ID: saga
+       service_description:
+         name: flight-booking-service
+         version: 0.0.1
+       servicecomb:
+         service:
+           registry:
+             address: http://sc.servicecomb.io:30100 
#此处选择使用ServiceComb的Service Center
+         rest:
+           address: 0.0.0.0:8080
+         handler:
+           chain:
+             Consumer:
+               default: loadbalance
+       ```
+
+       在 *saga-demo/docker-compose.yaml* 设置部署脚本
+       ```yaml
+       version: '2.1'
+
+       services:
+         service-center: #此处选择使用ServiceComb的Service Center容器镜像
+           image: "servicecomb/service-center"
+           hostname: service-center
+           ports:
+             - "30100:30100"
+
+         mysql:  #此处选择使用5.7版本的mysql镜像
+           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
+       ```
+
+3. 在Saga项目的根目录执行编译,制作Saga、机票预订、租车、酒店预订和支付服务镜像
+
+       ```bash
+       mvn package -DskipTests -Pdocker -Pdemo
+       ```
+
+4. 在Saga项目的saga-demo目录通过docker-compose一键启动Saga、机票预订、租车、酒店预订和支付服务
+
+       ```bash
+       docker-compose up
+       ```
+
+## 验证
+
+1. 参照 [Saga 
API](https://github.com/apache/servicecomb-saga/blob/master/docs/api/api.md) 
说明,设定各服务的事务、补偿、依赖和恢复参数,并保存为 *request.json* 文件
+
+       ```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"
+                 }
+               }
+             }
+           }
+         ]
+       }
+       ```
+
+2. 发送请求到Saga
+
+       ```bash
+       curl -XPOST -H "Content-Type: text/plain" -d @./request.json  
http://<localhost.ip:8083>/requests
+       ```
+
+    获取处理结果成功(如果失败,返回相应的错误信息)
+       ```bash
+       success
+       ```
+
+3. 查看Saga的事务
+
+       ```bash
+       curl -XGET http://<localhost.ip:8083>/events
+       ```
+
+    查询结果
+
+       ```bash
+       {
+           "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-servic [...]
+               },
+               {
+                   "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\\\ [...]
+               },
+               {
+                   "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  \\\"sta [...]
+               },
+               {
+                   "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,\\ [...]
+               },
+               {
+                   "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}}, \" [...]
+               },
+               {
+                   "id": 10,
+                   "sagaId": "bcd27f0d-6b82-49b3-8067-b16eba970e55",
+                   "creationTime": "2017-09-20T00:30:25Z",
+                   "type": "SagaEndedEvent",
+                   "contentJson": "{}"
+               }
+       ]
+       }
+       ```
+
+4. demo中模拟了支付服务帐户余额不足场景,发送请求超过一次将触发补偿操作。再次发送请求,可以在Saga日志中找到补偿事件
+
+       ```bash
+       {
+           "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-servic [...]
+               },
+               {
+                   "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,\\ [...]
+               },
+               {
+                   "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  \\\"sta [...]
+               },
+               {
+                   "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\\\ [...]
+               },
+               {
+                   "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}}, \" [...]
+               },
+               {
+                   "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,\\ [...]
+               },
+               {
+                   "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  \\\"sta [...]
+               },
+               {
+                   "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\\\ [...]
+               },
+               {
+                   "id": 23,
+                   "sagaId": "2654fa50-71e2-4fc8-afc2-6a5e0d3dafe9",
+                   "creationTime": "2017-09-20T00:31:15Z",
+                   "type": "SagaEndedEvent",
+                   "contentJson": "{}"
+               }
+           ]
+       }
+       ```
+
+## 下一步
+
+* 了解更多[ServiceComb中的数据最终一致性方案 - part 1](/cn/docs/distributed_saga_1/)
+
+* 了解更多[ServiceComb中的数据最终一致性方案 - part 2](/cn/docs/distributed_saga_2/)
+
+* 了解更多[ServiceComb中的数据最终一致性方案 - part 3](/cn/docs/distributed_saga_3/)
diff --git a/_docs/quick-start-dataconsistency.md 
b/_docs/quick-start-dataconsistency.md
index a8a17ec..be2a0f3 100755
--- a/_docs/quick-start-dataconsistency.md
+++ b/_docs/quick-start-dataconsistency.md
@@ -1,462 +1,462 @@
----
-title: "Data consistency solution"
-lang: en
-ref: quick-start-dataconsistency
-permalink: /docs/quick-start-dataconsistency/
-excerpt: "Introduce how to use Saga data consistency solution provided by 
ServiceComb"
-last_modified_at: 2017-09-03T10:01:43-04:00
----
-
-{% include toc %}
-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
-
-![Saga-demo]({{ site.url }}{{ site.baseurl }}/assets/images/saga-demo.png)
-
-## Running Demo
-
-Note, demo is in the 
[ServiceComb-Saga](https://github.com/apache/servicecomb-saga) project.
-
-1. Prerequisites
-- [Oracle JDK 
1.8](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html)
-- [Maven 3.x](https://maven.apache.org/install.html)
-- [Docker](https://www.docker.com/get-docker)
-- [MySQL](https://dev.mysql.com/downloads/)
-- [Service Center](https://github.com/apache/servicecomb-service-center)
-- [Docker compose](https://docs.docker.com/compose/install/)
-
-2. Configuration
-       Set service center address of each microservice in *microservice.yaml* 
file
-
-       ```yaml
-       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
-
-       ```yaml
-       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
-       ```
-
-3. Run the following command to create docker images in saga project root 
folder
-
-       ```bash
-       mvn package -DskipTests -Pdocker -Pdemo
-       ```
-
-4. Start application up in saga/saga-demo/ with the following command
-
-       ```bash
-       docker-compose up
-       ```
-
-## Verify services
-
-1. Use [Saga 
API](https://github.com/apache/servicecomb-saga/blob/master/docs/api/api.md) to 
set request content and save it to *request.json*
-
-       ```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"
-                 }
-               }
-             }
-           }
-         ]
-       }
-       ```
-
-2. Set content type to *text/plain*, and send *request.json* to Saga
-
-       ```bash
-       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)
-
-       ```bash
-       success
-       ```
-
-3. Get all the Saga events
-
-       ```bash
-       curl -XGET http://<localhost.ip:8083>/events
-       ```
-
-       Response
-
-       ```bash
-       {
-           "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-servic [...]
-               },
-               {
-                   "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\\\ [...]
-               },
-               {
-                   "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  \\\"sta [...]
-               },
-               {
-                   "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,\\ [...]
-               },
-               {
-                   "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}}, \" [...]
-               },
-               {
-                   "id": 10,
-                   "sagaId": "bcd27f0d-6b82-49b3-8067-b16eba970e55",
-                   "creationTime": "2017-09-20T00:30:25Z",
-                   "type": "SagaEndedEvent",
-                   "contentJson": "{}"
-               }
-       ]
-       }
-       ```
-
-4. 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.
-
-       ```bash
-       {
-           "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-servic [...]
-               },
-               {
-                   "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,\\ [...]
-               },
-               {
-                   "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  \\\"sta [...]
-               },
-               {
-                   "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\\\ [...]
-               },
-               {
-                   "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}}, \" [...]
-               },
-               {
-                   "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,\\ [...]
-               },
-               {
-                   "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  \\\"sta [...]
-               },
-               {
-                   "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\\\ [...]
-               },
-               {
-                   "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](/docs/distributed_saga_1/)
-
-* Learn more from [Eventual Data Consistency Solution in ServiceComb - part 
2](/docs/distributed_saga_2/)
-
-* Learn more from [Eventual Data Consistency Solution in ServiceComb - part 
3](/docs/distributed_saga_3/)
+---
+title: "Data consistency solution"
+lang: en
+ref: quick-start-dataconsistency
+permalink: /docs/quick-start-dataconsistency/
+excerpt: "Introduce how to use Saga data consistency solution provided by 
ServiceComb"
+last_modified_at: 2017-09-03T10:01:43-04:00
+---
+
+{% include toc %}
+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
+
+![Saga-demo]({{ site.url }}{{ site.baseurl }}/assets/images/saga-demo.png)
+
+## Running Demo
+
+Note, demo is in the 
[ServiceComb-Saga](https://github.com/apache/servicecomb-saga) project.
+
+1. Prerequisites
+- [Oracle JDK 
1.8](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html)
+- [Maven 3.x](https://maven.apache.org/install.html)
+- [Docker](https://www.docker.com/get-docker)
+- [MySQL](https://dev.mysql.com/downloads/)
+- [Service Center](https://github.com/apache/servicecomb-service-center)
+- [Docker compose](https://docs.docker.com/compose/install/)
+
+2. Configuration
+       Set service center address of each microservice in *microservice.yaml* 
file
+
+       ```yaml
+       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
+
+       ```yaml
+       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
+       ```
+
+3. Run the following command to create docker images in saga project root 
folder
+
+       ```bash
+       mvn package -DskipTests -Pdocker -Pdemo
+       ```
+
+4. Start application up in saga/saga-demo/ with the following command
+
+       ```bash
+       docker-compose up
+       ```
+
+## Verify services
+
+1. Use [Saga 
API](https://github.com/apache/servicecomb-saga/blob/master/docs/api/api.md) to 
set request content and save it to *request.json*
+
+       ```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"
+                 }
+               }
+             }
+           }
+         ]
+       }
+       ```
+
+2. Set content type to *text/plain*, and send *request.json* to Saga
+
+       ```bash
+       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)
+
+       ```bash
+       success
+       ```
+
+3. Get all the Saga events
+
+       ```bash
+       curl -XGET http://<localhost.ip:8083>/events
+       ```
+
+       Response
+
+       ```bash
+       {
+           "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-servic [...]
+               },
+               {
+                   "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\\\ [...]
+               },
+               {
+                   "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  \\\"sta [...]
+               },
+               {
+                   "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,\\ [...]
+               },
+               {
+                   "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}}, \" [...]
+               },
+               {
+                   "id": 10,
+                   "sagaId": "bcd27f0d-6b82-49b3-8067-b16eba970e55",
+                   "creationTime": "2017-09-20T00:30:25Z",
+                   "type": "SagaEndedEvent",
+                   "contentJson": "{}"
+               }
+       ]
+       }
+       ```
+
+4. 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.
+
+       ```bash
+       {
+           "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-servic [...]
+               },
+               {
+                   "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,\\ [...]
+               },
+               {
+                   "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  \\\"sta [...]
+               },
+               {
+                   "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\\\ [...]
+               },
+               {
+                   "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}}, \" [...]
+               },
+               {
+                   "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,\\ [...]
+               },
+               {
+                   "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  \\\"sta [...]
+               },
+               {
+                   "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\\\ [...]
+               },
+               {
+                   "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](/docs/distributed_saga_1/)
+
+* Learn more from [Eventual Data Consistency Solution in ServiceComb - part 
2](/docs/distributed_saga_2/)
+
+* Learn more from [Eventual Data Consistency Solution in ServiceComb - part 
3](/docs/distributed_saga_3/)
diff --git a/_posts/cn/2018-04-04-saga-pack-design.md 
b/_posts/cn/2018-04-04-saga-pack-design.md
index 11e2918..959b84f 100644
--- a/_posts/cn/2018-04-04-saga-pack-design.md
+++ b/_posts/cn/2018-04-04-saga-pack-design.md
@@ -99,12 +99,12 @@ omega的使用很简单,以一个简化的转账业务为例,同一笔转账
 1. 引入依赖
    ```xml
    <dependency>
-     <groupId>org.apache.servicecomb.saga</groupId>
+     <groupId>org.apache.servicecomb.pack</groupId>
      <artifactId>omega-spring-starter</artifactId>
      <version>0.1.0</version>
    </dependency>
    <dependency>
-     <groupId>org.apache.servicecomb.saga</groupId>
+     <groupId>org.apache.servicecomb.pack</groupId>
      <artifactId>omega-transport-resttemplate</artifactId>
      <version>0.1.0</version>
    </dependency>
diff --git a/_posts/cn/2018-04-28-saga_with_cucumber.md 
b/_posts/cn/2018-04-28-saga_with_cucumber.md
index 755dbb6..36807ec 100644
--- a/_posts/cn/2018-04-28-saga_with_cucumber.md
+++ b/_posts/cn/2018-04-28-saga_with_cucumber.md
@@ -207,7 +207,7 @@ Saga在Cucumber中集成了byteman注入一个超时异常,测试Saga对超时
 
    ```yaml
    RULE set the saga timeout to 5s
-   INTERFACE org.apache.servicecomb.saga.omega.context.annotations.SagaStart
+   INTERFACE org.apache.servicecomb.pack.omega.context.annotations.SagaStart
    METHOD timeout
    AT EXIT
    IF TRUE
@@ -215,7 +215,7 @@ Saga在Cucumber中集成了byteman注入一个超时异常,测试Saga对超时
    ENDRULE
 
    RULE sleep when postBooking until timeout happens
-   CLASS org.apache.servicecomb.saga.demo.pack.booking.BookingController
+   CLASS org.apache.servicecomb.pack.demo.pack.booking.BookingController
    METHOD postBooking
    AT ENTRY
    IF TRUE

Reply via email to