SpringCloud整合Hmily实现TCC分布式事务案例详解

蓝色幻想 2024-06-05 ⋅ 34 阅读

介绍

在分布式微服务架构中,实现一致性的分布式事务是一个非常重要且具有挑战性的问题。TCC(Try-Confirm-Cancel)是一种流行的解决方案,可以在不同的服务之间实现分布式事务的原子性和一致性。SpringCloud是一套优秀的微服务框架,Hmily是一款轻量级的分布式事务解决方案。

本文将详细介绍如何使用SpringCloud整合Hmily实现TCC分布式事务,并给出一个完整的案例。

准备工作

在开始之前,我们需要准备以下环境和工具:

  • JDK 1.8
  • Maven
  • IntelliJ IDEA
  • Docker

架构设计

我们的案例中包含两个微服务:订单服务和库存服务。订单服务负责创建订单,并调用库存服务减少库存;库存服务负责减少库存。

整个流程如下:

  1. 订单服务发起分布式事务,创建订单。
  2. 订单服务调用库存服务,减少库存。
  3. 如果减少库存成功,订单服务确认分布式事务,完成订单创建。
  4. 如果减少库存失败,订单服务取消分布式事务,回滚订单创建。

项目搭建

创建订单服务

使用Spring Initializr创建一个新的Spring Boot项目,命名为order-service

pom.xml文件中添加以下依赖:

<dependency>
    <groupId>org.hmily</groupId>
    <artifactId>hmily-springcloud</artifactId>
    <version>2.1.4.RELEASE</version>
</dependency>

application.properties文件中添加以下配置:

spring.application.name=order-service
server.port=8081

创建OrderController类,实现订单创建接口:

@RestController
public class OrderController {

    @Autowired
    private OrderService orderService;

    @PostMapping("/createOrder")
    public String createOrder(@RequestBody Order order) {
        return orderService.createOrder(order);
    }
}

创建OrderService接口:

public interface OrderService {

    String createOrder(Order order);
}

创建OrderServiceImpl类,实现订单服务:

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private InventoryService inventoryService;

    @Override
    @HmilyTCC(confirmMethod = "confirm", cancelMethod = "cancel")
    public String createOrder(Order order) {
        orderMapper.insert(order);
        inventoryService.reduceStock(order.getProductId(), order.getAmount());
        return "Order created successfully";
    }

    public void confirm(Order order) {
        // nothing to do
    }

    public void cancel(Order order) {
        orderMapper.delete(order.getId());
    }
}

创建库存服务

使用Spring Initializr创建一个新的Spring Boot项目,命名为inventory-service

pom.xml文件中添加以下依赖:

<dependency>
    <groupId>org.hmily</groupId>
    <artifactId>hmily-springcloud</artifactId>
    <version>2.1.4.RELEASE</version>
</dependency>

application.properties文件中添加以下配置:

spring.application.name=inventory-service
server.port=8082

创建InventoryController类,实现库存服务接口:

@RestController
public class InventoryController {

    @Autowired
    private InventoryService inventoryService;

    @PostMapping("/reduceStock")
    public String reduceStock(@RequestParam("productId") Long productId, @RequestParam("amount") Integer amount) {
        inventoryService.reduceStock(productId, amount);
        return "Stock reduced successfully";
    }
}

创建InventoryService接口:

public interface InventoryService {

    void reduceStock(Long productId, Integer amount);
}

创建InventoryServiceImpl类,实现库存服务:

@Service
public class InventoryServiceImpl implements InventoryService {

    @Autowired
    private InventoryMapper inventoryMapper;

    @Override
    @HmilyTCC(confirmMethod = "confirm", cancelMethod = "cancel")
    public void reduceStock(Long productId, Integer amount) {
        Inventory inventory = inventoryMapper.selectByProductId(productId);
        inventory.setStock(inventory.getStock() - amount);
        inventoryMapper.update(inventory);
    }

    public void confirm(Long productId, Integer amount) {
        // nothing to do
    }

    public void cancel(Long productId, Integer amount) {
        Inventory inventory = inventoryMapper.selectByProductId(productId);
        inventory.setStock(inventory.getStock() + amount);
        inventoryMapper.update(inventory);
    }
}

部署与测试

启动MySQL数据库

使用Docker启动一个MySQL数据库实例:

docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql

创建数据库和表

在MySQL数据库中创建一个名为test的数据库,然后执行以下SQL语句创建orderinventory表:

CREATE TABLE `order` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `product_id` bigint(20) DEFAULT NULL,
  `amount` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `inventory` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `product_id` bigint(20) DEFAULT NULL,
  `stock` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

启动微服务

在订单服务和库存服务的根目录下执行以下命令启动微服务:

mvn spring-boot:run

测试分布式事务

使用curl命令测试订单创建接口:

curl -X POST -H "Content-Type: application/json" -d '{"productId": 1, "amount": 10}' http://localhost:8081/createOrder

可以看到返回结果为Order created successfully,表示订单创建成功。

同时,我们可以在MySQL数据库中查看order表和inventory表的数据,确认分布式事务的一致性是否得到了保证。

总结

通过本案例,我们了解了如何使用SpringCloud整合Hmily实现TCC分布式事务。TCC通过Try、Confirm和Cancel三个阶段实现分布式事务的原子性和一致性。SpringCloud提供了与Hmily的无缝整合,使用起来非常方便。

希望本文对于你理解SpringCloud整合Hmily实现TCC分布式事务有所帮助。如果有任何问题,欢迎留言讨论。


全部评论: 0

    我有话说: