当前位置: 首页 > news >正文

SpringCloud之Seata(二)

4.Seata如何应用于项目?

安装seata及修改配置

4.1 官网下载Seata安装包

4.2 修改seata/config.txt

4.2.1 修改存储方式

store.db.dbType=mysql
store.db.driverClassName=com.mysql.jdbc.Driver
store.db.url=jdbc:mysql://你的IP:3306/seata?useUnicode=true
store.db.user=root
store.db.password=root

4.2.2 添加如下配置

service.vgroupMapping.demo-order=default
service.vgroupMapping.demo-storage=default
service.vgroupMapping.demo-account=default

4.3 修改seata/conf/registry.conf

4.3.1 注册中心改为nacos

registry {# file 、nacos 、eureka、redis、zk、consul、etcd3、sofatype = "nacos"nacos {application = "seata-server"serverAddr = "你的IP:8848"group = "SEATA_GROUP"namespace = ""cluster = "default"username = "nacos"password = "nacos"}

4.3.2 配置中心也改为nacos

config {# file、nacos 、apollo、zk、consul、etcd3type = "nacos"nacos {serverAddr = "你的IP:8848"namespace = "在nacos中创建一个命名空间,用来保存seata配置,提前配置好"group = "SEATA_GROUP"username = "nacos"password = "nacos"}

4.4 执行nacos脚本,推送seata配置到nacos

sh nacos-config.sh -h 你的nacos -p 8848 -g SEATA_GROUP -t 上面创建的命名空间 -u nacos -w nacos
创建seata需要用到的表

4.4.1 创建数据库

create database seata;

4.4.2 创建相关表

global_table: 全局事务表,每当有一个全局事务发起后,就会在该表中记录全局事务的ID

branch_table: 分支事务表,记录每一个分支事务的 ID,分支事务操作的哪个数据库等信息

lock_table: 全局锁

CREATE TABLE `branch_table` (`branch_id` bigint(20) NOT NULL,`xid` varchar(128) NOT NULL,`transaction_id` bigint(20) DEFAULT NULL,`resource_group_id` varchar(32) DEFAULT NULL,`resource_id` varchar(256) DEFAULT NULL,`branch_type` varchar(8) DEFAULT NULL,`status` tinyint(4) DEFAULT NULL,`client_id` varchar(64) DEFAULT NULL,`application_data` varchar(2000) DEFAULT NULL,`gmt_create` datetime(6) DEFAULT NULL,`gmt_modified` datetime(6) DEFAULT NULL,PRIMARY KEY (`branch_id`),KEY `idx_xid` (`xid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;CREATE TABLE `global_table` (`xid` varchar(128) NOT NULL,`transaction_id` bigint(20) DEFAULT NULL,`status` tinyint(4) NOT NULL,`application_id` varchar(32) DEFAULT NULL,`transaction_service_group` varchar(32) DEFAULT NULL,`transaction_name` varchar(128) DEFAULT NULL,`timeout` int(11) DEFAULT NULL,`begin_time` bigint(20) DEFAULT NULL,`application_data` varchar(2000) DEFAULT NULL,`gmt_create` datetime DEFAULT NULL,`gmt_modified` datetime DEFAULT NULL,PRIMARY KEY (`xid`),KEY `idx_gmt_modified_status` (`gmt_modified`,`status`),KEY `idx_transaction_id` (`transaction_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;CREATE TABLE `lock_table` (`row_key` varchar(128) NOT NULL,`xid` varchar(96) DEFAULT NULL,`transaction_id` bigint(20) DEFAULT NULL,`branch_id` bigint(20) NOT NULL,`resource_id` varchar(256) DEFAULT NULL,`table_name` varchar(32) DEFAULT NULL,`pk` varchar(36) DEFAULT NULL,`gmt_create` datetime DEFAULT NULL,`gmt_modified` datetime DEFAULT NULL,PRIMARY KEY (`row_key`),KEY `idx_branch_id` (`branch_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

启动seata服务

sh seata/bin/seata-server.sh 启动成功后,监听8091端口

在这里插入图片描述

看下nacos中是否注册了此服务: 看到如下内容表示,seata已经安装并注册成功

在这里插入图片描述

项目整合seata

1. 创建父工程
在ams-demo下创建父工程demo-seata,并修改父工程打包方式为pom

2. 添加依赖


<dependencies><!-- 配置读取 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId></dependency><!-- 单元测试 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- Spring Cloud & Alibaba --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId></dependency><!-- 注册中心 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency><!-- 配置中心 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><dependency><groupId>com.ams</groupId><artifactId>common-mybatis-plus</artifactId><version>1.0.0</version></dependency><dependency><groupId>com.ams</groupId><artifactId>common-base</artifactId><version>${ams.version}</version></dependency><dependency><groupId>com.ams</groupId><artifactId>common-web</artifactId><version>${ams.version}</version></dependency><!-- openfeign依赖 1. http客户端选择okhttp 2. loadbalancer替换ribbon --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-okhttp</artifactId></dependency><!--seata 必备--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId></dependency></dependencies>

4.4.3 创建订单子模块(库存、账户子模块类似)

1. 在demo-seata下创建demo-order子模块

2. 添加创建订单的接口

/*** @description:创建订单控接口*/
@RestController
@RequestMapping("/order")
@RequiredArgsConstructor
public class OrderController {private final OrderService orderService;@RequestMapping("/createOrder")public R createOrder() {orderService.createOrder();return R.ok("订单创建成功");}
}

3. 添加创建订单的service


/*** @description:创建订单service*/
@Service
@RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {private final AccountFeignService accountFeignService;private final StorageFeignService storageFeignService;@Override@GlobalTransactional(name = "ams-create-order",rollbackFor = Exception.class)public R createOrder() {Order order = Order.builder().count(10).money(100).productId(1L).status(0).userId(1L).build();// 创建订单save(order);// 扣除库存storageFeignService.decrease(order.getProductId(), order.getCount());// 扣余额accountFeignService.decrease(order.getUserId(), order.getMoney());//更新订单状态order.setStatus(1);updateById(order);return R.ok();}
}

4. 添加调用库存接口的feign

/*** Description:调用库存接口的feign*/
@FeignClient(value = "ams-demo-storage")
@RequestMapping("/storage")
public interface StorageFeignService {@RequestMapping("/decrease")public R decrease(@RequestParam("productId") Long productId, @RequestParam("count") Integer count);
}

5. 添加调用账户接口的feign

/*** Description:调用账户接口的feign*/
@FeignClient(value = "ams-demo-account")
@RequestMapping("/account")
public interface AccountFeignService {@RequestMapping("/decrease")public R decrease(@RequestParam("userId") Long userId, @RequestParam("money") Integer money);
}

6. 创建启动类

/*** @description:订单启动类*/
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableDiscoveryClient
@EnableFeignClients
public class DemoOrderApp {public static void main(String[] args) {SpringApplication.run(DemoOrderApp.class, args);}
}

7. 创建bootstrap.yml

server:port: 20003spring:application:name: ams-demo-ordercloud:nacos:# 注册中心discovery:server-addr: http://你的nacos地址:8848# 配置中心config:server-addr: ${spring.cloud.nacos.discovery.server-addr}file-extension: yamlshared-configs[0]:data-id: ams-common.yamlrefresh: truealibaba:seata:tx-service-group: demo-order

8. 新增nacos配置:

在naocs中创建ams-demo-order.yaml配置


spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://${mysql.host}:${mysql.port}/ams_order?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=trueusername: ${mysql.username}password: ${mysql.password}redis:database: 0host: ${redis.host}port: ${redis.port}password: ${redis.password}cache:# 缓存类型type: redis# 缓存时间(单位:ms)redis:time-to-live: 3600000# 缓存null值,防止缓存穿透cache-null-values: true# 允许使用缓存前缀,use-key-prefix: true# 缓存前缀,没有设置使用注解的缓存名称(value)作为前缀,和注解的key用双冒号::拼接组成完整缓存keykey-prefix: 'admin:'mybatis-plus:configuration:# 驼峰下划线转换map-underscore-to-camel-case: true# 这个配置会将执行的sql打印出来,在开发或测试的时候可以用log-impl: org.apache.ibatis.logging.stdout.StdOutImpl# 全局参数设置
ribbon:ReadTimeout: 120000ConnectTimeout: 10000SocketTimeout: 10000MaxAutoRetries: 0MaxAutoRetriesNextServer: 1 feign:httpclient:enabled: trueokhttp:enabled: false
#Seata分布式事务配置(AT模式)
seata:enabled: trueapplication-id: ${spring.application.name}#客户端和服务端在同一个事务组tx-service-group: demo-orderenable-auto-data-source-proxy: trueservice:vgroup-mapping:demo-order: defaultconfig:type: nacosnacos:namespace: "填写在安装seata时创建的命名空间"serverAddr: 你的nacos ip:8848group: SEATA_GROUPusername: "nacos"password: "nacos"#服务注册到nacosregistry:type: nacosnacos:application: seata-serverserver-addr: 你的nacos ip:8848group: SEATA_GROUPnamespace: "public"username: "nacos"password: "nacos"cluster: default
logging:level:spring: info

9. 创建回滚表

在每个业务数据库下面创建回滚表


CREATE TABLE `undo_log` (`branch_id` bigint(20) NOT NULL COMMENT 'branch transaction id',`xid` varchar(128) 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(6) NOT NULL COMMENT 'create datetime',`log_modified` datetime(6) NOT NULL COMMENT 'modify datetime',UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='AT transaction mode undo table';

10. 验证

启动三个服务,请求:http://localhost:20003/order/createOrder,通过设置异常,观察是否全局回滚 ​





上一篇跳转—SpringCloud之Seata(一)



本文主要参考链接:
SpringCloud实战|8.SpringCloud 整合 seata1.3-估计是全网讲的最细的并且一次成功的



随心所往,看见未来。Follow your heart,see light!

欢迎点赞、关注、留言,收藏及转发,一起学习、交流!

http://www.lryc.cn/news/20043.html

相关文章:

  • 【Redis-入门阶段】基本数据结构
  • BACnet协议详解————MS/TP物理层,数据链路层和网络层
  • Tomcat
  • 创客匠人直播:构建公域到私域的用户增长模型
  • 机试指南
  • Android CTA认证设定首选网络类型
  • Android 动态切换应用图标方案
  • SMART PLC斜坡函数功能块(梯形图代码)
  • 不那么认真的linux复习
  • Redis系列文章总纲
  • 更新丨三大模块升级,助力高效交付商业项目!
  • C++回顾(二)——const和引用
  • MXNet中使用双向循环神经网络BiRNN对文本进行情感分类<改进版>
  • DNS 域名解析
  • Spring MVC 源码- ViewResolver 组件
  • 【Hello Linux】初识冯诺伊曼体系
  • mysql索引,主从多个核心主题去探索问题。
  • 前端一面必会面试题(边面边更)
  • 【Hello Linux】初识操作系统
  • 完美的vue3动态渲染菜单路由全程
  • 2023年CDGA考试模拟题库(301-400)
  • Linux-常见命令
  • 2.25测试对象分类
  • 【Zabbix实战之部署篇】Zabbix客户端的安装部署方法
  • 【CSS】CSS 层叠样式表 ② ( CSS 引入方式 - 内嵌样式 )
  • MySQL事务与索引
  • 【编程入门】应用市场(php版)
  • 文化:你所在的团队,有多少人敢讲真话?
  • Linux | 项目自动化构建工具 - make/Makefile
  • Spring源码该如何阅读?十年架构师带来的Spring源码解析千万不要错过!