参考资料:
《Spring Microservices in Action》
《Spring Cloud Alibaba 微服务原理与实战》
《B站 尚硅谷 SpringCloud 框架开发教程 周阳》
《Seata 中文官网》
《Seata GitHub 官网》
《Seata 官方示例》
Seata 是一款开源的分布式业务解决方案,致力于在微服务架构下供给高功用和简单易用的分布式业务服务;它供给了 AT、TCC、Saga 和 XA 业务形式,为开发者供给了一站式的分布式业务解决方案;
Seata 的 AT 形式依据 1 个大局 ID 和 3 个组件模型:
Seata 服务端的存储形式有三种:file、db 和 redis:
服务分组的作业机制:
首先,在应用程序中需求装备业务分组,也便是运用 GlobalTransactionScanner 构造办法中的 txServiceGroup 参数,这个参数有如下几种赋值办法:
Seata 装置的是 AT 模型中的 TC,为便利理解这儿称为服务端;
Seata 作为一个业务中间件,有很多种布置装置办法,有装置包布置、源码布置和 Docker 布置,这儿介绍前两种。版别选 1.4.2;
修正存储形式:
修正 MySQL 衔接信息:
在 MySQL 上新建数据库和表;
-- 判别数据库存在,存在再删除 DROP DATABASE IF EXISTS seata; -- 创立数据库,判别不存在,再创立 CREATE DATABASE IF NOT EXISTS seata; -- 运用数据库 USE seata; -- 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(128), `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;
注册中心:
装备中心:
将 Seata 客户端和服务端的装备信息上传到 Nacos 服务器:
<dependency> <groupId>com.alibaba.cloudgroupId> <artifactId>spring-cloud-starter-alibaba-seataartifactId> dependency>
另一种装备办法:
@Configuration public class DataSourceProxyConfig { @Bean @ConfigurationProperties(prefix = "spring.datasource") public DataSource dataSource() { return new DruidDataSource();
} @Bean public DataSourceProxy dataSourceProxy(DataSource dataSource) { return new DataSourceProxy(dataSource);
} @Bean public SqlSessionFactory sqlSessionFactoryBean(DataSourceProxy dataSourceProxy) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSourceProxy); return sqlSessionFactoryBean.getObject();
}
}
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
AT 形式是依据 XA 业务模型演进而来的,所以它的整体机制也是一个改进版的两阶段提交协议;
举例:
假如 tx1 的二阶段大局回滚,则 tx1 需求从头获取该数据的本地锁,进行反向补偿的更新操作,完结分支的回滚;
在数据库本地业务阻隔级别读已提交(Read Committed) 或以上的基础上,Seata(AT 形式)的默许大局阻隔级别是读未提交(Read Uncommitted) ;