seata


Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。

简介

从一个简单的微服务实例来理解。

用户购买商品的业务逻辑。整个业务逻辑由3个微服务提供支持:

  • 仓储服务:对给定的商品扣除仓储数量。
  • 订单服务:根据采购需求创建订单。
  • 帐户服务:从用户帐户中扣除余额。

seata1

我们希望当任一事务进行回滚时,其他事务也跟着回滚,保持事务的一致性。但由于三个服务拥有自己的本地事务,导致事务不一致,容易造成脏数据。关于分布式事务的解决方案,我们希望能尽量跟业务代码解耦,而seata正是符合要求的一个解决方案。

seata2

开启全局事务

seata是通过代理数据源,在进行数据库操作的时候,通过RPC和TC之间进行通信,所以我们需要做的就是,将数据源交给seata代理,自己不进行初始化。

  1. 添加事务组配置
spring:
  cloud:
    alibaba:
      seata:
        tx-service-group: tcc_tx_group   
seata:
  enabled: true
  registry:
    type: nacos
    nacos:
      server-addr: localhost
  config:
    type: nacos
    nacos:
      server-addr: localhost
  1. 所属服务的数据库需要添加表
CREATE TABLE IF NOT EXISTS `undo_log`
(
    `id`            BIGINT(20)   NOT NULL AUTO_INCREMENT COMMENT 'increment id',
    `branch_id`     BIGINT(20)   NOT NULL COMMENT 'branch transaction id',
    `xid`           VARCHAR(100) NOT NULL COMMENT 'global transaction id',
    `context`       VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',
    `rollback_info` LONGBLOB     NOT NULL COMMENT 'rollback info',
    `log_status`    INT(11)      NOT NULL COMMENT '0:normal status,1:defense status',
    `log_created`   DATETIME     NOT NULL COMMENT 'create datetime',
    `log_modified`  DATETIME     NOT NULL COMMENT 'modify datetime',
    PRIMARY KEY (`id`),
    UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
  AUTO_INCREMENT = 1
  DEFAULT CHARSET = utf8 COMMENT ='AT transaction mode undo table';
  1. 通过@GlobalTransactional注解即能开启一个全局事务。
public class BusinessServiceImpl implements BusinessService {

	// 仓储服务
    private StorageService storageService;

    // 订单服务
    private OrderService orderService;

    /**
     * 采购
     */
     @GlobalTransactional
    public void purchase(String userId, String commodityCode, int orderCount) {

    	// 扣除仓储数量
        storageService.deduct(commodityCode, orderCount);

        // 创建订单,并从账户服务中扣除余额
        orderService.create(userId, commodityCode, orderCount);
    }