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.rhkb.cn/news/245147.html

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

相关文章

BGP路由反射-数据中心IDC项目经验

一、背景描述 R1,R2,R3在AS200区域内&#xff0c;R1和R2,R1和R3建立OSPF&#xff0c;宣告接口互联. AS200区域内&#xff0c;R1和R2建立IBGP, R1和R3建立IBGP R2和R4建立EBGP, R3和R5建立EBGP。 网络拓扑&#xff1a; 二、故障现象 R1和R2可以收到来自AS100区域R4的E…

pytorch实战-6手写数字加法机-迁移学习

1 概述 迁移学习概念&#xff1a;将已经训练好的识别某些信息的网络拿去经过训练识别另外不同类别的信息 优越性&#xff1a;提高了训练模型利用率&#xff0c;解决了数据缺失的问题&#xff08;对于新的预测场景&#xff0c;不需要大量的数据&#xff0c;只需要少量数据即可…

Unity通用渲染管线升级URP、HDRP

Unity通用渲染管线升级URP、HDRP 一、Build-in Pipline升级到 URP 一、Build-in Pipline升级到 URP 安装URP包 升级所有材质&#xff08;升级完成后材质会变成紫红色&#xff0c;Shader丢失&#xff0c;此为正常现象&#xff09; 创建 UniversalRenderPipelineAsset 配置文…

Nacos 在云原生架构下的演进

作者&#xff1a;之卫 背景 Nacos 提供的最核心能力是动态服务发现与动态配置管理能力&#xff0c;在云原生环境下&#xff0c;借助云产品&#xff0c;如 EDAS&#xff08;企业级分布式应用服务&#xff09;平台中&#xff0c;我们可以很轻松地使用 K8s 来托管 Nacos 体系的微…

蓝桥杯(Python)每日练Day5

题目 OJ1229 题目分析 题目完全符合栈的特征&#xff0c;后进先出。如果能够熟练使用列表的9种方法那么这道题很容易解出。 题解 a[]#存衣服 nint(input()) for i in range(n):llist(input().split())#判断每一步的操作if len(l[0])2:a.append(l[1])else:while a.pop()!l…

大数据平台红蓝对抗 - 磨利刃,淬精兵!

背景 目前大促备战常见备战工作&#xff1a;专项压测&#xff08;全链路压测、内部压测&#xff09;、灾备演练、降级演练、限流、巡检&#xff08;监控、应用健康度&#xff09;、混沌演练&#xff08;红蓝对抗&#xff09;&#xff0c;如下图所示。随着平台业务越来越复杂&a…

LabVIEW探测器CAN总线系统

介绍了一个基于FPGA和LabVIEW的CAN总线通信系统&#xff0c;该系统专为与各单机进行系统联调测试而设计。通过设计FPGA的CAN总线功能模块和USB功能模块&#xff0c;以及利用LabVIEW开发的上位机程序&#xff0c;系统成功实现了CAN总线信息的收发、存储、解析及显示功能。测试结…

Obsidian笔记软件结合cpolar实现安卓移动端远程本地群晖WebDAV数据同步

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

使用Robot Framework实现多平台自动化测试

基于Robot Framework、Jenkins、Appium、Selenium、Requests、AutoIt等开源框架和技术&#xff0c;成功打造了通用自动化测试持续集成管理平台&#xff08;以下简称“平台”&#xff09;&#xff0c;显著提高了测试质量和测试用例的执行效率。 01、设计目标 平台通用且支持不…

Hadoop基本概论

目录 一、大数据概论 1.大数据的概念 2.大数据的特点 3.大数据应用场景 二、Hadoop概述 1.Hadoop定义 2.Hadoop发展历史 3.Hadoop发行版本 4.Hadoop优势 5.Hadoop1.x/2.x/3.x 6.HDFS架构 7.Yarn架构 8.MapReduce架构 9.大数据技术生态体系 一、大数据概论 1.大数…

docker 基础手册

文章目录 docker 基础手册docker 容器技术镜像与容器容器与虚拟机docker 引擎docker 架构docker 底层技术docker 二进制安装docker 镜像加速docker 相关链接docker 生态 docker 基础手册 docker 容器技术 开源的容器项目&#xff0c;使用 Go 语言开发原意“码头工人”&#x…

[极客大挑战 2019]LoveSQL1

万能密码测试&#xff0c;发现注入点 注意这里#要使用url编码才能正常注入 测试列数&#xff0c;得三列 查看table&#xff0c;一个是geekuser另一个是l0ve1ysq1 查看column&#xff0c;有id&#xff0c;username&#xff0c;password&#xff0c;全部打印出来&#xff0c;…

【数据结构】 顺序表的基本操作 (C语言版)

一、顺序表 1、顺序表的定义&#xff1a; 线性表的顺序存储结构&#xff0c;即将表中的结点按逻辑顺序依次存放在一组地址连续的存储单元里。这种存储方式使得在逻辑结构上相邻的数据元素在物理存储上也是相邻的&#xff0c;可以通过数据元素的物理存储位置来反映其逻辑关系。…

SSL证书DV和OV的区别

SSL证书是数字证书的一种&#xff0c;配置在服务器上&#xff0c;起到文件信息传输加密的作用。由受信任的数字证书颁发机构CA在验证服务器身份后颁发&#xff0c;防止第三方窃取或篡改信息。 在选择SSL证书的过程中&#xff0c;一般要注意选择的SSL证书的等级。常见有DV和OV证…

单片机面向对象思维的架构:时间轮片法

今天分享一篇单片机程序框架的文章。 程序架构重要性 很多人尤其是初学者在写代码的时候往往都是想一点写一点&#xff0c;最开始没有一个整体的规划&#xff0c;导致后面代码越写越乱&#xff0c;bug不断。 最终代码跑起来看似没有问题(有可能也真的没有问题)&#xff0c;但…

清越 peropure·AI 国内版ChatGP新功能介绍

当OpenAI发布ChatGPT的时候,没有人会意识到,新一代人工智能浪潮将给人类社会带来一场眩晕式变革。其中以ChatGPT为代表的AIGC技术加速成为AI领域的热门发展方向,推动着AI时代的前行发展。面对技术浪潮,清越科技(PeroPure)立足多样化生活场景、精准把握用户实际需求,持续精确Fin…

差分进化算法求解基于移动边缘计算 (MEC) 的无线区块链网络的联合挖矿决策和资源分配(提供MATLAB代码)

一、优化模型介绍 在所研究的区块链网络中&#xff0c;优化的变量为&#xff1a;挖矿决策&#xff08;即 m&#xff09;和资源分配&#xff08;即 p 和 f&#xff09;&#xff0c;目标函数是使所有矿工的总利润最大化。问题可以表述为&#xff1a; max ⁡ m , p , f F miner …

255:vue+openlayers 加载tomtom地图(多种形式)

第255个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+openlayers中添加tomtom地图,这里包含了多种形式,诸如中文标记、英文标记、白天地图、晚上地图、卫星影像图,高山海拔地形图等。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果 文章目录 示…

vue3和vite项目在scss中因为本地图片,不用加~

看了很多文章说要加~&#xff0c;真的好坑哦&#xff0c;我的加了~反而出不来了&#xff1a; 304 Not Modified 所以需要去掉~&#xff1a; /* 默认dark主题 */ :root[themered] {--bg-color: #0d1117;--text-color: #f0f6fc;--backImg: url(/assets/images/redBg.png); }/* …

鸿蒙开发踩坑之dataPreferences数据存储后获取为空

问题 在开发中通过PreferencesUtil.setValue(name, 旺财)设置后&#xff0c;通过IDE运行App后获取之前存储的数据都为空。 问题原因 查看控制台&#xff0c;发现如下&#xff1a; $ hdc shell am force-stop com.happy.xxx $ hdc shell bm uninstall com.happy.xxx$ hdc fi…