Transaction ID(XID):
全局唯一的事务ID;TC - 事务协调者:
维护全局和分支事务的状态,驱动全局事务提交或回滚;TC(Server端)为单独服务端部署;TM - 事务管理器:
定义全局事务的范围:开始全局事务、提交或回滚全局事务;RM - 资源管理器:
管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。TM和RM(Client端)由业务系统集成。其实就是一个微服务,来保证分布式事务
service模块
service模块:修改group属性 ; service { #vgroup->rgroup # service模块:修改自定义事务组的名称 vgroup_mapping.my_test_tx_group = "shuzhan_group" #only support single node default.grouplist = "127.0.0.1:8091" #degrade current not support enableDegrade = false #disable disable = false #unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanent max.commit.retry.timeout = "-1" max.rollback.retry.timeout = "-1" }store模块
存储模式,默认为file,修改为db; store { ## store mode: file、db # 存储模式,默认为file,修改为db mode = "db" ## file store file { dir = "sessionStore" # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions max-branch-session-size = 16384 # globe session size , if exceeded throws exceptions max-global-session-size = 512 # file buffer size , if exceeded allocate new buffer file-write-buffer-cache-size = 16384 # when recover batch read size session.reload.read_size = 100 # async, sync flush-disk-mode = async }数据库设置
上面修改后的db存储数据的数据库地址; ## database store db { ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc. datasource = "dbcp" ## mysql/oracle/h2/oceanbase etc. # 数据库地址 db-type = "mysql" driver-class-name = "com.mysql.jdbc.Driver" url = "jdbc:mysql://60.205.229.31:3307/seata" user = "root" password = "123456" min-conn = 1 max-conn = 3 global.table = "global_table" branch.table = "branch_table" lock-table = "lock_table" query-limit = 100 }order建表sql
CREATE TABLE `se_order` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '表id', `user_id` bigint(20) DEFAULT NULL COMMENT '用户id', `product_id` bigint(20) DEFAULT NULL COMMENT '产品id', `count` int(11) DEFAULT NULL COMMENT '数量', `money` decimal(11,0) DEFAULT NULL COMMENT '金额', `status` int(11) DEFAULT NULL COMMENT '订单状态(0为创建中,1为已完成)', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;storage建表sql
CREATE TABLE `storage` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '表id', `product_id` bigint(20) DEFAULT NULL COMMENT '产品id', `total` int(10) DEFAULT NULL COMMENT '总库存', `used` int(10) DEFAULT NULL COMMENT '消耗库存', `leftover` int(10) DEFAULT NULL COMMENT '剩余库存', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;account建表sql
CREATE TABLE `account` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '表主键', `user_id` bigint(20) DEFAULT NULL COMMENT '用户id', `total` decimal(50,0) DEFAULT NULL COMMENT '总额度', `used` decimal(50,0) DEFAULT NULL COMMENT '已用额度', `leftover` decimal(50,0) DEFAULT NULL COMMENT '剩余额度', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;三个库的回滚表
对应的sql在seata/conf/db_undo_log.sql; 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;pom.xml
<dependencies> <!--seata的相关依赖--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-seata</artifactId> <!--里面自带的依赖为0.7.9--> <exclusions> <exclusion> <groupId>io.seata</groupId> <artifactId>seata-all</artifactId> </exclusion> </exclusions> </dependency> <!--尽量和服务端的版本保持一致--> <dependency> <groupId>io.seata</groupId> <artifactId>seata-all</artifactId> <version>0.9.0</version> </dependency> <!--web模块,这两个一般绑定在一起--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--nacos注册中心--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--openfeign服务调用--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!--mybatis与springboot的整合--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <!--阿里巴巴的druid连接池--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> </dependency> <!--mysql数据库--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--swagger依赖--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency> <!--lombok插件--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>application.yaml
server: port: 9001 spring: application: name: day-dreamer-order # 数据源只要设置好,并不需要额外的配置 datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: org.gjt.mm.mysql.Driver url: jdbc:mysql://60.205.229.31:3307/seata_order username: root password: 123456 # 服务注册的Nacos地址:用IP加宿主机端口,不用写http cloud: nacos: discovery: server-addr: 120.79.28.20:9001 alibaba: seata: # 自定义事务组名称, # 需要和seata-server中的seata/conf/file.conf的service模块保持一致 tx-service-group: shuzhan_group feign: client: config: default: connectTimeout: 5000 readTimeout: 5000 mybatis: mapper-locations: classpath:com.day.dreamer.order.*.xml type-aliases-package: com.day.dreamer.order.domainfile.conf
将上述seata-server中修改完的file.conf复制,保存在业务微服务中,修改自定义事务组的名称;service部分,store部分,db部分 service { #vgroup->rgroup # 修改自定义事务组的名称:shuzhan_group,这里为啥和seata-server端配置的不太一样 vgroup_mapping.shuzhan_group = "default" #only support single node default.grouplist = "127.0.0.1:8091" #degrade current not support enableDegrade = false #disable disable = false #unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanent max.commit.retry.timeout = "-1" max.rollback.retry.timeout = "-1" } store { ## store mode: file、db # 存储模式,默认为file,修改为db mode = "db" ## file store file { dir = "sessionStore" # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions max-branch-session-size = 16384 # globe session size , if exceeded throws exceptions max-global-session-size = 512 # file buffer size , if exceeded allocate new buffer file-write-buffer-cache-size = 16384 # when recover batch read size session.reload.read_size = 100 # async, sync flush-disk-mode = async } db { ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc. datasource = "dbcp" ## mysql/oracle/h2/oceanbase etc. # 数据库地址 db-type = "mysql" driver-class-name = "com.mysql.jdbc.Driver" url = "jdbc:mysql://60.205.229.31:3307/seata" user = "root" password = "123456" min-conn = 1 max-conn = 3 global.table = "global_table" branch.table = "branch_table" lock-table = "lock_table" query-limit = 100 } }registry.conf
将上面seata-server改好后的配置registry.conf文件,也复制在该工程中;没看懂这一步要干啥,seata_server中是为了把seata_server注册到注册中心,但微服务在application.yaml中已经注册过了啊; registry { # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa # 默认为file,改成注册到nacos type = "nacos" nacos { serverAddr = "120.79.28.20:9001" namespace = "" cluster = "default" }