399 Star 1.7K Fork 494

闲.大赋(李家智)/BeetlSQL

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

一个模拟Spring应用,Saga事务的管理,假设用户有4元余额,想购买一个3元产品

如下是购买流程

String orderAddUrl = "http://127.0.0.1:8081/order/item/{orderId}/{userId}/{fee}";
String userBalanceUpdateUrl = "http://127.0.0.1:8082/user/fee/{orderId}/{userId}/{fee}";
SagaContext sagaContext = SagaContext.sagaContextFactory.current();
try {
    sagaContext.start(gid);
    //模拟调用俩个微服务,订单和用户
    rest.postForEntity(orderAddUrl, null,String.class, paras);
    rest.postForEntity(userBalanceUpdateUrl, null,String.class, paras);
    if (1 == 1) {
        throw new RuntimeException("模拟失败,查询saga-server 看效果");
    }
} catch (Exception e) {
    sagaContext.rollback();
    return e.getMessage();
}

  • 浏览器访问DemoApplication的swagger,调用buy/{gid},这里gid为任意订单号。执行操作,系统应该分别调用用户和订单系统,获取余额,增加订单和扣费 在调用成功后,模拟一个失败验证能否回滚。
  • 浏览器访问Saga-server 的swagger,查询所有事务API,http://127.0.0.1:18081/api/v1/allRollbackTask ,返回内如下 可以看到事务在三个系统中都回滚成功
{
  "success": true,
  "msg": "成功",
  "data": [
    {
      "id": "a717d181-608b-4f99-ab8a-9c60e83cce12",
      "gid": "123",
      "appName": "userSystem",
      "status": "Success",
      "rollbackStatus": "Success",
      "time": 1138055785025836,
      "taskInfo": "{\"tasks\":[{\"@Clazz\":\"org.beetl.sql.saga.ms.client.SagaClientTransaction$KafkaSagaTaskTrace\",\"rollbackTask\":{\"@Clazz\":\"org.beetl.sql.saga.common.ami.SagaUpdateByIdAMI$UpdateSagaRollbackTask\",\"sqlManagerName\":\"mySqlManager\",\"obj\":{\"@Clazz\":\"org.beetl.sql.saga.demo.entity.UserEntity\",\"id\":\"xiandafu\",\"name\":\"闲大赋\",\"balance\":4}},\"success\":false}],\"success\":true}",
      "createTime": 1607864163823,
      "updateTime": 1607864164067
    },
    {
      "id": "c4765a46-cf2f-4d7a-a714-dc35bf723df2",
      "gid": "123",
      "appName": "orderSystem",
      "status": "Success",
      "rollbackStatus": "Success",
      "time": 1138055465293352,
      "taskInfo": "{\"tasks\":[{\"@Clazz\":\"org.beetl.sql.saga.ms.client.SagaClientTransaction$KafkaSagaTaskTrace\",\"rollbackTask\":{\"@Clazz\":\"org.beetl.sql.saga.common.ami.SagaInsertAMI$InsertSagaRollbackTask\",\"sqlManagerName\":\"mySqlManager\",\"entityClass\":\"org.beetl.sql.saga.demo.entity.OrderEntity\",\"pkId\":\"4a40f48b-4b29-4b62-8d47-5f3867b03afd\"},\"success\":false}],\"success\":true}",
      "createTime": 1607864163570,
      "updateTime": 1607864164058
    },
    {
      "id": "48eb2fbe-9ff8-4913-bfd2-63176b3646b4",
      "gid": "123",
      "appName": "demoSystem",
      "status": "Error",
      "rollbackStatus": "Success",
      "time": 1138055258883126,
      "taskInfo": "{\"tasks\":[],\"success\":true}",
      "createTime": 1607864163543,
      "updateTime": 1607864164052
    }
  ],
  "errorCode": 0
}

status字段标识业务执行是否成功,rollbackStatus标识回滚是否执行成功,如上可以看到userSystem 系统和orderSystem都执行成功,但demoSystem执行失败抛出异常,导致所有三个系统都回滚

  • 因为回滚成功,应该能继续调用/buy/{gid},并不会抛出余额不足
  • 查看各个系统的beetlsql 日志,会发现反向操作成功执行
  • 查看Saga-server 的Swagger ,可以看到回滚任务执行结果
  • 可以订阅各个TOPIC,了解回滚任务是如何发送到Saga-Server,以及如何从Saga—Server获取回滚任务
  • 可以在SagaClientConfig.retry方法打断点,了解各个client如何开始真正回滚

如下为是使用的topic和数据库


./kafka-topics.sh --delete --zookeeper 127.0.0.1:2181 --topic saga-client-demoSystem
./kafka-topics.sh --delete --zookeeper 127.0.0.1:2181 --topic saga-client-userSystem
./kafka-topics.sh --delete --zookeeper 127.0.0.1:2181 --topic saga-client-orderSystem
./kafka-topics.sh --delete --zookeeper 127.0.0.1:2181 --topic saga-server-topic
rm -rf ~/.h2
ls
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Java
1
https://gitee.com/xiandafu/beetlsql.git
git@gitee.com:xiandafu/beetlsql.git
xiandafu
beetlsql
BeetlSQL
master

搜索帮助