根据官网的quickstart https://seata.apache.org/zh-cn/docs/user/quickstart/
官方讲解了对应的服务结构,并提供了实例代码
按照要求启动seata服务,这里我使用docker安装
docker run -d --name seata-server \
-p 8091:8091 \
seataio/seata-server
获取demo源代码,gitee找了一个镜像fork下来
使用熟悉的技术栈对应的实例代码
查看配置文件,发现服务需要db以及dubbo需要zk作为注册中心。
使用docker启动对应的db和zk
创建对应的数据库和表(每个服务中有对应的sql文件,执行一份就行,都是一样的)
修改对应配置并启动相关服务
这里主要修改了db的链接和账号密码,以及zk的连接地址,seata使用file作为registry和config-center
另,源代码的日志依赖有问题导致启动失败,进行了一些调整。
梳理代码流程并测试
整体流程如图
- bisiness 购买商品
- storage 扣除对应商品的库存
- order 创建订单
- order 计算金额
- account 扣除用户账户的金额
- order 增加订单记录
代码演示
- business服务 购买方法 提交对应用户购买一定数量的对应商品
// 开启分布式事务控制
@GlobalTransactional(timeoutMills = 300000, name = "spring-dubbo-tx")
public void purchase(String userId, String commodityCode, int orderCount) {
LOGGER.info("purchase begin ... xid: " + RootContext.getXID());
// 根据商品编号减少库存
storageService.deduct(commodityCode, orderCount);
// just test batch update
//stockService.batchDeduct(commodityCode, orderCount);
// 为用户创建指定商品的订单
orderService.create(userId, commodityCode, orderCount);
// 此处随机失败
if (random.nextBoolean()) {
throw new RuntimeException("random exception mock!");
}
}
- 库存服务直接删除对应库存
@Override
public void deduct(String commodityCode, int count) {
LOGGER.info("Stock Service Begin ... xid: " + RootContext.getXID());
LOGGER.info("Deducting inventory SQL: update stock_tbl set count = count - {} where commodity_code = {}", count,
commodityCode);
jdbcTemplate.update("update stock_tbl set count = count - ? where commodity_code = ?",
count, commodityCode);
LOGGER.info("Stock Service End ... ");
}
- 订单服务中扣除对应账号金额 并创建订单
@Override
public void create(String userId, String commodityCode, int orderCount) {
LOGGER.info("Order S