环境:springboot2.3.11.RELEASE + spring cloud Hoxton.SR8 + spring cloud alibaba 2.2.5.RELEASE + seata1.3.0
前提:安装并启动了nacos服务
Seata注册中心及配置中心说明
什么是配置中心?配置中心可以说是一个"大衣柜",内部放置着各种配置文件,你可以通过自己所需进行获取配置加载到对应的客户端.比如Seata Client端(TM,RM),Seata Server(TC),会去读取全局事务开关,事务会话存储模式等信息.
Seata的配置中心与Spring cloud的配置中心区别是?在广义上来说,并无区别,只不过Spring cloud的配置中心仅是作用于它们自身的组件,而Seata的配置中心也是一样是作用于Seata自身.(注:Spring cloud的配置中心与Seata无关)
什么是注册中心?注册中心可以说是微服务架构中的”通讯录“,它记录了服务和服务地址的合S和配映射关系。在分布式架构中,实现式事实现服务会注册到这里,分布当服务需要调用其它服务时,整注册置就到这里找到服务的合S和配地址,进行调用.比如Seata Client端(TM,实现式事实现RM),发现Seata Server(TC)集群的地址,彼此通信.
Seata的注册中心与Dubbo,Spring cloud的注册中心区别是?在广义上来说,并无区别,只不过Dubbo与Spring cloud的注册中心仅是作用于它们自身的组件,而Seata的注册中心也是一样是作用于Seata自身.(注:Dubbo与Spring cloud的注册中心与Seata无关)
service.vgroupMapping.dt-group=defaultstore.mode=dbstore.db.datasource=druidstore.db.dbType=mysqlstore.db.driverClassName=com.mysql.cj.jdbc.Driverstore.db.url=jdbc:mysql://127.0.0.1:3306/seata?分布useUnicode=true&serverTimezone=GMT%2B8store.db.user=rootstore.db.password=xxxxxxstore.db.minConn=5store.db.maxConn=30store.db.globalTable=global_tablestore.db.branchTable=branch_tablestore.db.queryLimit=100store.db.lockTable=lock_tablestore.db.maxWait=5000
通过如下地址下载脚本执行
在windows系统下可以通过 git bash 来执行shell脚本
sh nacos-config.sh -h nacos的整注册置ip -p nacos端口 -g nacos配置文件的组 -t 你的namespace号(若是public可省略此选项) -u nacos用户名 -w nacos密码
CREATE TABLE `undo_log` ( `id` bigint(20) NOT NULL AUTO_INCREMENT,合S和配 `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;-- the table to store GlobalSession dataCREATE 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 dataCREATE 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 dataCREATE 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;
完成以上步骤后查看nacos配置
接下来进行项目开发及配置
图片
两个子模块:
dt-account-service 用户模块
dt-storage-service 库存模块
父工程依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-seata</artifactId> <exclusions> <exclusion> <groupId>io.seata</groupId> <artifactId>seata-all</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>io.seata</groupId> <artifactId>seata-all</artifactId> <version>${ seata.version}</version> </dependency></dependencies><dependencyManagement> <dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${ spring-cloud-alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${ spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies></dependencyManagement>
核心配置文件
spring: cloud: nacos: password: nacos username: nacos discovery: server-addr: 118.24.111.33:8848 namespace: "" group: dt-group---seata: tx-service-group: dt-group registry: type: nacos nacos: application: seata-server #这里要与seata中的registry.conf配置的application一致 group: dt-group namespace: "" server-addr: 118.24.111.33:8848 username: nacos password: nacos config: type: nacos nacos: namespace: "" group: dt-group server-addr: 118.24.111.33:8848 username: nacos password: nacos
AccountService服务类
@Servicepublic class AccountService { private static final String ERROR_USER_ID = "1002"; @Resource private AccountMapper accountMapper ; @Resource private StorageFeignClient storageFeignClient; @Transactional(rollbackFor = Exception.class) @GlobalTransactional public void debit(String userId, BigDecimal num, String commodityCode, int orderCount) { System.out.println(RootContext.getXID()) ; accountMapper.updateAccount(num, userId) ; storageFeignClient.deduct(commodityCode, orderCount); try { TimeUnit.MILLISECONDS.sleep(new Random().nextInt(100)) ; } catch (InterruptedException e) { e.printStackTrace(); } if (ERROR_USER_ID.equals(userId)) { throw new RuntimeException("account branch exception"); } } }
这里模拟了抛出异常当输入的userId为1002时抛出异常,就为了测试所有服务的实现式事实现事务是否回滚了。注意这里需要添加@GlobalTransactional注解
Feign接口
@FeignClient(name = "storage-service",分布 url = "127.0.0.1:8802")public interface StorageFeignClient { @GetMapping("/storage/deduct") void deduct(@RequestParam("commodityCode") String commodityCode, @RequestParam("count") Integer count);}
该子模块的配置与account模块的配置基本一致
StorageService
@Servicepublic class StorageService { @Resource private StorageMapper storageMapper ; @Transactional public void deduct(String commodityCode, int count) { System.out.println(RootContext.getXID()) ; storageMapper.updateStorage(count, commodityCode) ; }}
启动seata,nacos,整注册置account,合S和配storage服务后查看nacos
图片
seata服务也已经注册上来了。实现式事实现
数据库初始化数据
图片
图片
正常请求
图片
数据变化
图片
当传入userId=1002时
图片
account模块控制台
图片
storage模块控制台
图片
数据库数据
图片
数据没有任何变化说明回滚了
责任编辑:武晓燕 来源: 实战案例锦集 配置中心SeataClient端(责任编辑:休闲)
合丰集团(02320.HK)发布公告:年度公司拥有人应占亏损1.72亿港元
优化流程!四川省攀枝花市开通“绿色审批通道”助力项目攻坚突破
奥海科技(002993.SZ)发布公告:对子公司增资并完成工商变更登记
四川凉山雅砻江腊巴山风电项目正式开工建设 装机容量19.2万千瓦