Spring Cloud Alibaba Seata学习


Seata分TC、TM和RM三个角色,TC(Server端)为单独服务端部署,TM和RM(Client端)由业务系统集成。
本文参考官网:https://seata.io

1 基础配置

使用nacos作为注册中心和配置中心

1.1 seata-server配置

版本1.4.2

1.1.1 修改register.conf

位置:{SEATA_HOME}/conf/register.conf
内容如下:

registry {
  type = "nacos"

  nacos {
    application = "seata-server"
    serverAddr = "127.0.0.1:8848"
    group = "SEATA_GROUP"
    namespace = ""
    cluster = "default"
    username = "nacos"
    password = "nacos"
  }
}
config {
  type = "nacos"

  nacos {
    serverAddr = "127.0.0.1:8848"
    namespace = ""
    group = "SEATA_GROUP"
    username = "nacos"
    password = "nacos"
    dataId = "seataServer.properties"
  }
}

1.1.2 修改config.txt

下载config-conter中的config.txt和/nacos/nacos-config.sh
修改config.txt的内容

store.mode=db;
#数据库连接属性
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.jdbc.Driver
store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true
store.db.user=username
store.db.password=password
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000

Server端存储模式(store.mode)现有file、db、redis三种;
注: file模式为单机模式,全局事务会话信息内存中读写并持久化本地文件root.data,性能较高;
db模式为高可用模式,全局事务会话信息通过db共享,相应性能差些;

redis模式Seata-Server 1.3及以上版本支持,性能较高,存在事务信息丢失风险,请提前配置合适当前场景的redis持久化配置.

serverclient
store.mode: file,db,redisconfig.type: file、nacos 、apollo、zk、consul、etcd3、custom
#only db:#only file:
store.db.driverClassNameservice.default.grouplist
store.db.url#All:
store.db.userservice.vgroupMapping.my_test_tx_group
store.db.passwordservice.disableGlobalTransaction

1.1.3 上传config.txt配置

将config.txt的内容上传到nacos配置中心:先启动nacos,然后执行nacos-config.sh -h localhost -p 8848 -g SEATA_GROUP -t 5a3c7d6c-f497-4d68-a71a-2e5e3340b3ca -u username -w password
注:-t表示命名空间

1.1.4 建表

全局事务会话信息由3块内容构成,全局事务–>分支事务–>全局锁,对应表global_table、branch_table、lock_table
从官网获取脚本sql脚本,如下:

-- -------------------------------- The script used when storeMode is 'db' --------------------------------
-- the table to store GlobalSession data
CREATE TABLE IF NOT EXISTS `global_table`
(
    `xid`                       VARCHAR(128) NOT NULL,
    `transaction_id`            BIGINT,
    `status`                    TINYINT      NOT NULL,
    `application_id`            VARCHAR(32),
    `transaction_service_group` VARCHAR(32),
    `transaction_name`          VARCHAR(128),
    `timeout`                   INT,
    `begin_time`                BIGINT,
    `application_data`          VARCHAR(2000),
    `gmt_create`                DATETIME,
    `gmt_modified`              DATETIME,
    PRIMARY KEY (`xid`),
    KEY `idx_gmt_modified_status` (`gmt_modified`, `status`),
    KEY `idx_transaction_id` (`transaction_id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8;

-- the table to store BranchSession data
CREATE TABLE IF NOT EXISTS `branch_table`
(
    `branch_id`         BIGINT       NOT NULL,
    `xid`               VARCHAR(128) NOT NULL,
    `transaction_id`    BIGINT,
    `resource_group_id` VARCHAR(32),
    `resource_id`       VARCHAR(256),
    `branch_type`       VARCHAR(8),
    `status`            TINYINT,
    `client_id`         VARCHAR(64),
    `application_data`  VARCHAR(2000),
    `gmt_create`        DATETIME(6),
    `gmt_modified`      DATETIME(6),
    PRIMARY KEY (`branch_id`),
    KEY `idx_xid` (`xid`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8;

-- the table to store lock data
CREATE TABLE IF NOT EXISTS `lock_table`
(
    `row_key`        VARCHAR(128) NOT NULL,
    `xid`            VARCHAR(96),
    `transaction_id` BIGINT,
    `branch_id`      BIGINT       NOT NULL,
    `resource_id`    VARCHAR(256),
    `table_name`     VARCHAR(32),
    `pk`             VARCHAR(36),
    `gmt_create`     DATETIME,
    `gmt_modified`   DATETIME,
    PRIMARY KEY (`row_key`),
    KEY `idx_branch_id` (`branch_id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8;

1.1.5 启动seata-server

./seata-server.sh -h 127.0.0.1 -p 8091 -m db -n 1 -e test

 -h: 注册到注册中心的ip
-p: Server rpc 监听端口
-m: 全局事务会话信息存储模式,file、db、redis,优先读取启动参数 (Seata-Server 1.3及以上版本支持redis)
-n: Server node,多个Server时,需区分各自节点,用于生成不同区间的transactionId,以免冲突
-e: 多环境配置参考 http://seata.io/en-us/docs/ops/multi-configuration-isolation.html

1.2 seata-client配置

依赖:

<dependencies>
	<dependency>
       <groupId>com.alibaba.cloud</groupId>
       <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
    </dependency>
</dependencies>
<dependencyManagement>
	<dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2.2.6.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

yml:

seata:
  registry:
    nacos:
      server-addr: localhost:8848, localhost:8849
      application: seata-server #默认为seata-server
    type: nacos
  config:
    nacos:
      server-addr: localhost:8848, localhost:8849
      group: SEATA_GROUP #默认为SEATA_GROUP
    type: nacos
  tx-service-group: consumer-service #事务分组名

相应的需要在配置中心配置
service.vgroupMapping.consumer-service=default

说明:server-client根据tx-service-group: consumer-service从nacos配置中心读取service.vgroupMapping.consumer-service=default,也就是seata服务在nacos的集群名称(nacos中可以同一个服务可以有多个虚拟集群),然后找到对应的服务实例。

创建undo_log表

-- 注意此处0.3.0+ 增加唯一索引 ux_undo_log
CREATE TABLE `undo_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `branch_id` bigint(20) NOT NULL,
  `xid` varchar(100) NOT NULL,
  `context` varchar(128) NOT NULL,
  `rollback_info` longblob NOT NULL,
  `log_status` int(11) NOT NULL,
  `log_created` datetime NOT NULL,
  `log_modified` datetime NOT NULL,
  `ext` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

启动遇到的错误
Caused by: java.lang.NoClassDefFoundError: io/seata/spring/annotation/datasource/SeataAutoDataSourceProxyCreator
原因:使用的alibaba could的版本不支持seata

使用版本说明:https://github.com/alibaba/spring-cloud-alibaba/wiki/版本说明#组件版本关系

2 seata原理

GlobalTransactionalInterceptor(方法拦截器-解析@GlobalTransactional注解)–>TransactionalTemplate.execute(根据事务传播行为,开始事务、执行业务逻辑、提交事务)—>DefaultGlobalTransaction.begin(绑定xid)—>DefaultTransactionManager.begin(远程调用TC开启事务,并返回xid)

在这里插入图片描述

流程说明:TM向TC注册,RM向TC注册。TM向TC发起开启全局事务的请求,并获得xid,向调用链路传递xid。各个链路接口执行完成,提交本地事务之前,向TC注册分支并申请全局锁。获得锁后,提交本地事务,上报事务状态给TC,释放全局锁。TM向TC发起全局提交或回滚的请求,继而TC向RM发起分支提交或回滚的请求。

RM与TC的通信:
RM通过AbstractNettyRemotingClient的实现类RmNettyRemotingClient向TC注册,并注册一系列处理器(RmBranchCommitProcessor、RmBranchRollbackProcessor、RmUndoLogProcessor等),通过AbstractNettyRemotingClient中定义的ClientHandler(Net ty的ChannelInboundHandlerAdapter),接收TC的消息,并根据消息的code执行processor。
TM通过AbstractNettyRemotingClient的实现类TmNettyRemotingClient与TC通信。

详细参考:https://my.oschina.net/objcoding/blog/4367965

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值