概要

seata 是alibaba 出的一款分布式事务管理器,他有侵入性小,实现简单等特点。我们能够使用seata 实现分布式事务管理,

是微服务必备的组件。他可以实现在微服务之间的事务管理,也可以实现多个数据源的事务管理。

seata 在阿里内部,和众多的公司都有应用,因此我们可以放心的使用它。

实现的基本原理

SEATA 实现了几种事务模式,我们使用AT模式,他使用起来简单,代码侵入性小。

下图就是AT的事务过程。

 

 

TM是事务管理者

RM 资源管理者,可以认为是数据库。

TC 是事务协调者,就是SEATA 服务

TM 向 TC 申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的 XID。
XID 在微服务调用链路的上下文中传播。
RM 向 TC 注册分支事务,将其纳入 XID 对应全局事务的管辖。
TM 向 TC 发起针对 XID 的全局提交或回滚决议。
TC 调度 XID 下管辖的全部分支事务完成提交或回滚请求。

 实现方式

配置SEATA

引入相关JAR包

<dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
                <version>2.1.1.RELEASE</version>
                <scope>compile</scope>
                <exclusions>
                    <exclusion>
                        <groupId>io.seata</groupId>
                        <artifactId>seata-all</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>

            <dependency>
                <groupId>io.seata</groupId>
                <artifactId>seata-all</artifactId>
                <version>1.2.0</version>
            </dependency>

在resources 下增加文件 registry.conf,我的实现为使用nacos作为配置和注册中心

文件内容如下:

registry {
  type = "nacos"
  nacos {
    application = "seata-server"
    serverAddr = "192.168.31.10:8848"
    #namespace = "public"
    group = "DEFAULT_GROUP"
    #cluster = "default"
    #username = "nacos"
    #password = "nacos"
  }
}

config {
  type = "nacos"
  nacos {
    serverAddr = "192.168.31.10:8848"
    namespace = ""
    group = "SEATA_GROUP"
    cluster = "default"
    username = "nacos"
    password = "nacos"
  }
}

第一段是注册中心的配置,第二段为配置中心的配置,配置实际上是放到nacos 下的。

配置文件路径:

https://gitee.com/seata-io/seata/blob/develop/script/config-center/config.txt

可以把这个下下来,然后使用命令将这个配置,提交到 nacos,命令的路径为:

https://gitee.com/seata-io/seata/tree/develop/script/config-center/nacos

 

 我们可以如下执行命令:

nacos-config.sh -h nacos的IP -p nacos端口 -u nacos用户名 -w nacos密码

这个配置需要修改的地方:

 

service.vgroupMapping.bpm_tx_group=default
service.vgroupMapping.form_tx_group=default
service.vgroupMapping.portal_tx_group=default
service.vgroupMapping.user_tx_group=default
service.vgroupMapping.system_tx_group=default

这个配置 为 

service.vgroupMapping + 应用的配置 =default 

 

 这个default 对应上面的配置

 

 事务数据存储到数据库

 

 

 

 修改 数据库的配置,我们将配置导入到nacos 。

 

 同时,需要将刚刚的配置文件 registry.conf 拷贝到 seata 目录下

 

 配置好后需要先启动 nacos,在启动 seata

 nohup ./seata-server.sh -p 8888 -h 192.168.31.10 &

 

seata 数据库脚本:

https://gitee.com/seata-io/seata/blob/develop/script/server/db/mysql.sql

这样 事务配置就处理好了。

 

我们需要在微服务的每个数据库中增加 UNDO_LOG表。

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';

这个需要和微服务数据库在一起。

 

代码实现

@Bean("dataSource")
    @ConfigurationProperties(prefix = "spring.datasource")
    public DruidDataSource druidDataSource() {
        return new DruidDataSource();
    }



    @Bean("dataSourceProxy")
    public DataSourceProxy dataSourceProxy(@Qualifier("dataSource")DataSource dataSource) {
        DataSourceProxy proxy=new DataSourceProxy(dataSource);
        return proxy;
    }

 

 实际上我们在代码中使用的是 DataSourceProxy 代理过的数据源。

测试如下:

 

 在测试时,我们可以发现,通过RootContext  取得Xid。

 

posted on 2020-06-07 17:20  自由港  阅读(1657)  评论(0编辑  收藏  举报