Dubbo整合seata实现分布式事务

概览

本篇文章,根据官网代码demo演示而来
springboot、dubbo、seata实现分布式事务整合 DEMO

操作步骤如下:

  • 1.seata-server端,修改server配置
  • 2.client端(你自己的项目),引入配置文件,修改配置文件
  • 3.数据源代理设置
  • 4.创建数据库表
  • 5.启动注册中心(ZK),启动server,启动client(包括订单服务,库存服务)

1.此demo技术选型及版本信息

运行环境 版本要求
jdk 1.8+
Spring Boot 1.5+
MySQL 5.7+
ZooKeeper 3.4+
Seata 1.0.0
Dubbo 2.6.5

2.demo概况

  • springboot-base:存储公共调用的基类接口,mapper接口,Model层的类等,可mvn install后,供另外三个module调用。
  • springboot-dubbo-storage:库存服务;
  • springboot-dubbo-order:订单服务;
  • springboot-dubbo-client:RPC消费者,提供对外接口;

order服务关键代码如下:

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void createOrder(OrderDTO orderDTO) {
        //1、远程方法 扣减库存
        storageService.decreaseStorage(storageDTO);

        //2、本地方法 创建订单
        orderMapper.createOrder(order);

    }

3.创建业务数据库

  • seata_order:存储订单的数据库;
  • seata_storage:存储库存的数据库;

4.seata 组件

1,配置Seata数据源

/**
 * seata数据源
 *
 * init datasource proxy
 * @Param: druidDataSource  datasource bean instance
 * @Return: DataSourceProxy  datasource proxy
 */
@Bean
public DataSourceProxy dataSourceProxy(DruidDataSource druidDataSource){
    return new DataSourceProxy(druidDataSource);
}

2,Seata初始化

/**
 * 配置全局事务扫描器。有两个参数,一个是应用名称,一个是事务分组
 *
 * @return
 */
@Bean
public GlobalTransactionScanner globalTransactionScanner() {
    return new GlobalTransactionScanner("springboot-dubbo-storage", "my_test_tx_group");
}

3,配置注册中心,内容在file.conf和registry.conf。

4,注解标记事务方法,在订单创建的方法上,加上@GlobalTransactional注解即可。

5.启动测试(注意先后顺序)

依次启动Seata、springboot-dubbo-storage、springboot-dubbo-order、springboot-dubbo-client后,打开postman测试,配置测试参数为:

正常情况:

请求地址:http://localhost:18090/order/create

请求方式:post

请求内容(body):

{
    "userId":1,
    "productId":1,
    "count":10,
    "money":100
}

通过我们访问/order下单接口,根据响应的内容我们确定商品已经购买成功

数据库内的商品库存有所扣减

6.测试异常情况

我们模拟userId为666时,会出现异常

请求地址:http://localhost:18090/order/create

请求方式:post

请求内容(body):

{
    "userId":666,
    "productId":8,
    "count":5,
    "money":50
}
 @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void createOrder(OrderDTO orderDTO) {
        log.info("开始全局事务。XID=" + RootContext.getXID());

        // 库存
        StorageDTO storageDTO = new StorageDTO();
        storageDTO.setTotal(orderDTO.getCount());
        storageDTO.setProductId(orderDTO.getProductId());

        //1、远程方法 扣减库存
        storageService.decreaseStorage(storageDTO);

        //2、本地方法 创建订单
        orderDTO.setId(order_id.incrementAndGet());
        Order order = new Order();
        BeanUtils.copyProperties(orderDTO,order);
        orderMapper.createOrder(order);

        // 构造异常抛出 在addOrder报错后,会有全局事务的rollback过程
        if (orderDTO.getUserId() == 666) {
            throw new RuntimeException("分布式事务异常..." + orderDTO.getId());
        }
    }

此时我们可以发现下单后数据库数据并没有任何改变 ,扣减的库存和创建的订单都回滚了

参考链接

  • https://seata.io/zh-cn/
  • https://seata.io/zh-cn/docs/user/quickstart.html
  • https://seata.io/zh-cn/blog/springboot-dubbo-mybatisplus-seata.html
发布了402 篇原创文章 · 获赞 1317 · 访问量 173万+

猜你喜欢

转载自blog.csdn.net/fly910905/article/details/104198266
今日推荐