SpringCloud Aliba-Seata【下】-从入门到学废【8】

目录

1.数据库创建

1.seata_account库下建表

2.seata_order库下建表

3.seata_storage库下建表 

4.在每个库下创建回滚日志 

2.创建订单模块 

2.1建工程

2.2加pom

2.3改yml

2.4file.conf

2.5registry.conf

2.6domain

2.7Dao

2.8Service

2.9controller

2.10config配置

2.11主启动


 

1.数据库创建

  • 这里我们会创建三个服务,一个订单服务,一个库存服务,一个账户服务
  • 当用户下单时,会在订单服务中创建一个订单,然后通过远程调用库存服务来扣减下单商品的库存,再通过远程调用账户服务来扣减用户账户里面的余额,最后在订单服务中修改订单状态为已完成。

1.seata_account库下建表

CREATE TABLE `t_account` (`id` int NOT NULL,`user_id` int NOT NULL COMMENT '用户id',`total` decimal(20,0) NOT NULL COMMENT '总额度',`used` decimal(20,0) NOT NULL COMMENT '已用额度',`residue` decimal(20,0) NOT NULL COMMENT '剩余可用额度',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

2.seata_order库下建表

CREATE TABLE `t_order` (`id` int NOT NULL,`user_id` int NOT NULL COMMENT '用户id',`product_id` int NOT NULL COMMENT '产品id',`count` int NOT NULL COMMENT '数量',`money` decimal(20,0) NOT NULL COMMENT '金额',`status` int NOT NULL COMMENT '订单状态:0-创建中,1-已完结',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

3.seata_storage库下建表 

CREATE TABLE `t_storage` (`id` int NOT NULL,`product_id` int NOT NULL COMMENT '产品id',`total` int NOT NULL COMMENT '总库存',`used` int NOT NULL COMMENT '已用库存',`residue` int NOT NULL COMMENT '剩余库存',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

4.在每个库下创建回滚日志 

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;

2.创建订单模块 

2.1建工程

  • 1.在父工程下创建seata-order-service2001
  • 2.注意jdk和maven版本

2.2加pom

<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><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--mybatis--><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><version>1.2.16</version></dependency><!--mysql-connector-java--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--jdbc--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>org.example</groupId><artifactId>cloud-api-commons</artifactId><version>1.0-SNAPSHOT</version></dependency><!--springCloud alibaba Naocs--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--持久化--><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId></dependency><!--Sentinel--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><!--openFeign--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!--seata--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId><exclusions><exclusion><groupId>seata-all</groupId><artifactId>io.seata</artifactId></exclusion></exclusions></dependency><dependency><groupId>io.seata</groupId><artifactId>seata-all</artifactId><version>0.9.0</version></dependency>

2.3改yml

server:port: 2001
spring:application:name: seata-order-servicecloud:alibaba:seata:#自定义事务组需要与seat-server中的对应tx-service-group: xz_groupnacos:discovery:server-addr: 192.168.20.50:1111datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/seata_orderusername: rootpassword: 123456feign:sentinel:enabled: falselogging:level:io:seata: infomybatis:mapper-locations: classpath:mapper/*.xml

2.4file.conf

在resource下创建文件file.conf,直接粘贴seata的file.conf即可

transport {# tcp udt unix-domain-sockettype = "TCP"#NIO NATIVEserver = "NIO"#enable heartbeatheartbeat = true#thread factory for nettythread-factory {boss-thread-prefix = "NettyBoss"worker-thread-prefix = "NettyServerNIOWorker"server-executor-thread-prefix = "NettyServerBizHandler"share-boss-worker = falseclient-selector-thread-prefix = "NettyClientSelector"client-selector-thread-size = 1client-worker-thread-prefix = "NettyClientWorkerThread"# netty boss thread size,will not be used for UDTboss-thread-size = 1#auto default pin or 8worker-thread-size = 8}shutdown {# when destroy server, wait secondswait = 3}serialization = "seata"compressor = "none"
}
service {#vgroup->rgroupvgroup_mapping.my_test_tx_group = "xz_group"#only support single nodedefault.grouplist = "127.0.0.1:8091"#degrade current not supportenableDegrade = false#disabledisable = false#unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanentmax.commit.retry.timeout = "-1"max.rollback.retry.timeout = "-1"
}client {async.commit.buffer.limit = 10000lock {retry.internal = 10retry.times = 30}report.retry.count = 5tm.commit.retry.count = 1tm.rollback.retry.count = 1
}## transaction log store
store {## store mode: file、dbmode = "db"## file storefile {dir = "sessionStore"# branch session size , if exceeded first try compress lockkey, still exceeded throws exceptionsmax-branch-session-size = 16384# globe session size , if exceeded throws exceptionsmax-global-session-size = 512# file buffer size , if exceeded allocate new bufferfile-write-buffer-cache-size = 16384# when recover batch read sizesession.reload.read_size = 100# async, syncflush-disk-mode = async}## database storedb {## 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.cj.jdbc.Driver"url = "jdbc:mysql://127.0.0.1:3306/seata?serverTimezone=UTC"user = "root"password = "123456"min-conn = 1max-conn = 3global.table = "global_table"branch.table = "branch_table"lock-table = "lock_table"query-limit = 100}
}
lock {## the lock store mode: local、remotemode = "remote"local {## store locks in user's database}remote {## store locks in the seata's server}
}
recovery {#schedule committing retry period in millisecondscommitting-retry-period = 1000#schedule asyn committing retry period in millisecondsasyn-committing-retry-period = 1000#schedule rollbacking retry period in millisecondsrollbacking-retry-period = 1000#schedule timeout retry period in millisecondstimeout-retry-period = 1000
}transaction {undo.data.validation = trueundo.log.serialization = "jackson"undo.log.save.days = 7#schedule delete expired undo_log in millisecondsundo.log.delete.period = 86400000undo.log.table = "undo_log"
}## metrics settings
metrics {enabled = falseregistry-type = "compact"# multi exporters use comma dividedexporter-list = "prometheus"exporter-prometheus-port = 9898
}support {## springspring {# auto proxy the DataSource beandatasource.autoproxy = false}
}

2.5registry.conf

在resource下创建文件registryonf,直接粘贴seata的registry.conf即可

registry {# file 、nacos 、eureka、redis、zk、consul、etcd3、sofatype = "nacos"nacos {serverAddr = "192.168.20.50:1111"namespace = ""cluster = "default"}eureka {serviceUrl = "http://localhost:8761/eureka"application = "default"weight = "1"}redis {serverAddr = "localhost:6379"db = "0"}zk {cluster = "default"serverAddr = "127.0.0.1:2181"session.timeout = 6000connect.timeout = 2000}consul {cluster = "default"serverAddr = "127.0.0.1:8500"}etcd3 {cluster = "default"serverAddr = "http://localhost:2379"}sofa {serverAddr = "127.0.0.1:9603"application = "default"region = "DEFAULT_ZONE"datacenter = "DefaultDataCenter"cluster = "default"group = "SEATA_GROUP"addressWaitTime = "3000"}file {name = "file.conf"}
}config {# file、nacos 、apollo、zk、consul、etcd3type = "file"nacos {serverAddr = "localhost"namespace = ""}consul {serverAddr = "127.0.0.1:8500"}apollo {app.id = "seata-server"apollo.meta = "http://192.168.1.204:8801"}zk {serverAddr = "127.0.0.1:2181"session.timeout = 6000connect.timeout = 2000}etcd3 {serverAddr = "http://localhost:2379"}file {name = "file.conf"}
}

2.6domain

  • 1.创建封装类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult<T> {private Integer code;private String message;private  T data;public CommonResult(Integer code,String message){this.code=code;this.message=message;}
}
  • 2.创建实体类 
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Order {private Integer id;private Integer userId;private Integer productId;private Integer count;private BigDecimal money;private Integer status;
}

2.7Dao

@Mapper
public interface OrderDao {//1.新建订单void create(Order order);//2.修改订单状态;从0到1void update(@Param("userId") Integer userId, @Param("status") Integer status);}

2.8Service

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {@Resourceprivate OrderDao orderDao;@Resourceprivate StorageService storageService;@Resourceprivate AccountService accountService;@Override@GlobalTransactional(name = "xz_create_order",rollbackFor = Exception.class)public void create(Order order) {//1.新建订单log.info("====开始新建订单====");orderDao.create(order);//2.扣减库存log.info("====订单微服务开始调用库存,扣减count====start");storageService.decrease(order.getProductId(),order.getCount());log.info("====订单微服务开始调用库存,扣减count====end");//3.扣减账户log.info("====订单微服务开始调用账户,扣减money====start");accountService.decrease(order.getUserId(),order.getMoney());log.info("====订单微服务开始调用账户,扣减money====end");//4.修改订单状态log.info("====开始修改订单状态====start");orderDao.update(order.getUserId(),0);log.info("====开始修改订单状态====end");log.info("====下订单结束====");}
}
  • 使用openfeign创建AccountService 
@FeignClient(value = "seata-account-service")
public interface AccountService {@PostMapping(value = "/storage/decrease")CommonResult decrease(@RequestParam("userId")Integer userId,@RequestParam("money") BigDecimal money);
}
  • 使用openfeign创建StorageService 
@FeignClient(value = "seata-storage-service")
public interface StorageService {@PostMapping(value = "/storage/decrease")CommonResult decrease(@RequestParam("productId")Integer productId,@RequestParam("count")Integer count);
}

2.9controller

@RestController
public class OrderController {@Resourceprivate OrderService orderService;@GetMapping("/order/create")public CommonResult<Order> create(Order order){orderService.create(order);return new CommonResult<>(200,"订单创建成功");}
}

2.10config配置

@Configuration
public class DataSourceConfig {@Value("${mybatis.mapper-locations}")private String mapperLocations;@Bean@ConfigurationProperties(prefix = "spring.datasource")public DataSource dataSource(){return new DruidDataSource();}@Beanpublic DataSourceProxy dataSourceProxy(DataSource dataSource){return new DataSourceProxy(dataSource);}@Beanpublic SqlSessionFactory sqlSessionFactory(DataSourceProxy dataSourceProxy)throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean=new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSourceProxy);sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations));sqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory());return sqlSessionFactoryBean.getObject();}
}
@Configuration
@MapperScan("com.xz.springcloud.dao")
public class MybatisConfig {
}

2.11主启动

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableFeignClients
@EnableDiscoveryClient
public class SeataOrderMainApp2001 {public static void main(String[] args) {SpringApplication.run(SeataOrderMainApp2001.class);}
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/646499.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

对 MODNet 网络结构直接剪枝的探索

文章目录 1 写在前面2 遇到问题3 解决方案4 探索过程4.1 方案一4.2 方案二4.3 方案三 5 疑惑与思考5.1 Q15.2 Q2 1 写在前面 在前面的文章中&#xff0c;笔者与小伙伴们分享了对 MODNet 主干网络部分以及其余分支分别剪枝的探索历程&#xff0c;即先分解、再处理、后融合的手法…

C++:缺省参数函数重载

目录 C/C语言 函数调用的工作原理&#xff1a; 函数调用一般分为两个部分&#xff1a; 缺省参数&#xff1a; 缺省参数的分类&#xff1a; 全缺省参数 半缺省参数 注意事项&#xff1a; 缺省参数与C语言的调用参数对比&#xff1a; 函数重载&#xff1a; 函数重载…

pve8.1 安装、创建centos7虚拟机及配置

之前创建虚拟机centos7时&#xff0c;硬盘分配太大了&#xff0c;做成模板后无法进行修改了&#xff0c;安装完pve8.1后&#xff0c;强迫症犯了重新创建一下顺便记录一下配置过程。由于目前centos7还是生产用的比较多的版本所以本次还是安装centos7.9版本。 一、下载镜像 下载…

利用Redis List实现数据库分页快速查询的有效方法

目录 引言 传统数据库分页查询的挑战 Redis List的优势 利用Redis List实现分页查询 1. 数据准备 2. 分页查询 3. 分页缓存 4. 分页处理 结论 引言 随着Web应用程序的发展和用户数量的增加&#xff0c;数据库分页查询变得越来越常见。分页查询允许用户在大型数据集中…

JVM/GC复习

JVM/GC JVM(java虚拟机)MATjstack(将正在运行的JVM的线程进行快照并且打印出来)死锁VisualVM工具(监控线程内存使用情况)JMX GC垃圾回收算法1.引用计数法2.标记清除发3.标记压缩算法4.复制算法5.分代算法 收集器1.串行垃圾收集器2.并行垃圾收集器2.CMS垃圾收集器 3.G1垃圾收集器…

营销一体化平台如何助力企业增长?3个案例深度解析

无论大家怎么想&#xff0c;反对和批评的声音有多大&#xff0c;还是有很多企业从组织层面为CMO下了很多需要及时转化的KPI要求。 原因无外乎是增长乏力。再加上外部环境处在产业升级换代、科技革命在即的当口&#xff0c;企业比以往任何时候都意识到营销变革的重要性。 然而…

两相步进电机驱动原理

两相步进电机驱动 前言什么是步进电机驱动器细分控制电机内部结构图片步进电机驱动原理&#xff08;重要&#xff09;步进电机参数&#xff11;、步距角&#xff1a;收到一个脉冲转动的角度&#xff12;、细分数 &#xff1a;&#xff11;&#xff0f;&#xff12;&#xff0c…

清华大学对港澳台华侨生新增额外招生项目来啦

导读 众所周知的是&#xff0c;港澳台和华侨生录取清华大学和北京大学&#xff0c;除了港澳台联考&#xff0c;DSE申请等形式之外&#xff0c;那只有和普通内地高中生混在一起的录取方式。但是其实近些年来&#xff0c;清华大学也为尖子生开辟了新的录取方式&#xff0c;我们一…

Qt Quick程序的发布|Qt5中QML和Qt Quick 的更改

# Quick程序的发布旧版做法 # Qt5中QML和Qt Quick 的更改 1.QML语言的更改(Qt4->Qt5) 在QML语言中,只有少量更改会影响QML代码的迁移:无法直接导入单独的文件(例如:import"MyType.qml”),需要导人该文件所在的目录; JavaScript文件中的相对路径被解析…

线性代数:矩阵的定义

目录 一、定义 二、方阵 三、对角阵 四、单位阵 五、数量阵 六、行&#xff08;列&#xff09;矩阵 七、同型矩阵 八、矩阵相等 九、零矩阵 十、方阵的行列式 一、定义 二、方阵 三、对角阵 四、单位阵 五、数量阵 六、行&#xff08;列&#xff09;矩阵 七、同型矩…

手写一个图形验证码

文章目录 需求分析 需求 使用 JS 写一个验证码&#xff0c;并在前端进行校验 分析 新建文件 VueImageVerify.vue <template><div class"img-verify"><canvas ref"verify" :width"state.width" :height"state.height&qu…

河南嘉家购商贸有限公司获绿色积分信用认证

“实现绿色产业、打造完善的绿色产业链、走可持续发展共创共赢”。近日&#xff0c;河南嘉家购商贸有限公司获得绿色积分认证&#xff0c;确认了该企业在绿色消费积分领域的领先地位。 据了解&#xff0c;河南嘉家购商贸有限公司始终将绿色积分视为企业发展的核心要素。全面优化…

如何实现无公网ip远程访问本地websocket服务端【内网穿透】

文章目录 1. Java 服务端demo环境2. 在pom文件引入第三包封装的netty框架maven坐标3. 创建服务端,以接口模式调用,方便外部调用4. 启动服务,出现以下信息表示启动成功,暴露端口默认99995. 创建隧道映射内网端口6. 查看状态->在线隧道,复制所创建隧道的公网地址加端口号7. 以…

G1与ZGC

G1垃圾收集器(-XX:UseG1GC)详解 G1(Garbage-First)是一款面向服务器的垃圾收集器&#xff0c;主要针对配备多颗处理器及大容量内存的机器。以极高概率满足GC停顿时间要求的同时&#xff0c;还具备高吞吐量性能特性。 G1把内存区域划分为小格子(Region)&#xff0c;最多可以有2…

java常见的面试问题

目录 一、异常 1、 throw 和 throws 的区别&#xff1f; 2、 final、finally、finalize 有什么区别&#xff1f; 3、try-catch-finally 中哪个部分可以省略&#xff1f; 4、try-catch-finally 中&#xff0c;如果 catch 中 return 了&#xff0c;finally 还会执行吗&#…

大创项目推荐 题目:垃圾邮件(短信)分类 算法实现 机器学习 深度学习 开题

文章目录 1 前言2 垃圾短信/邮件 分类算法 原理2.1 常用的分类器 - 贝叶斯分类器 3 数据集介绍4 数据预处理5 特征提取6 训练分类器7 综合测试结果8 其他模型方法9 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于机器学习的垃圾邮件分类 该项目…

DP读书:在常工院的2023年度总结

DarrenPig的年度总结 这是最好的时代&#xff0c;这是最坏的时代。——狄更斯 这是最好的时代&#xff0c;这是最坏的时代。——狄更斯 这是最好的时代&#xff0c;这是最坏的时代。——狄更斯 一、2023我的感受 不就是2023吗&#xff0c;不就是一年的经历吗&#xff0c;大家…

Spring Boot 集成 API 文档 - Swagger、Knife4J、Smart-Doc

文章目录 1.OpenAPI 规范2.Swagger: 接口管理的利器3.Swagger 与 SpringFox&#xff1a;理念与实现4.Swagger 与 Knife4J&#xff1a;增强与创新5.案例&#xff1a;Spring Boot 整合 Swagger35.1 引入 Swagger3 依赖包5.2 优化路径匹配策略兼容 SpringFox5.3 配置 Swagger5.4 S…

硅像素传感器文献调研(九)3

欧洲X射线自由电子激光器抗辐射像素传感器的设计和初步试验 摘要 目前正在汉堡建造的欧洲X射线自由电子激光器的高强度和高重复率需要硅传感器&#xff0c;该传感器可以在高偏置电压下工作3年&#xff0c;承受高达1 GGy的X射线剂量。在AGIPD合作范围内&#xff0c;研究了由四家…

# [NOI2019] 斗主地 洛谷黑题题解

[NOI2019] 斗主地 题目背景 时限 4 秒 内存 512MB 题目描述 小 S 在和小 F 玩一个叫“斗地主”的游戏。 可怜的小 S 发现自己打牌并打不过小 F&#xff0c;所以他想要在洗牌环节动动手脚。 一副牌一共有 n n n 张牌&#xff0c;从上到下依次标号为 1 ∼ n 1 \sim n 1∼…