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

大型网站建设定制农产品网站开发背景

大型网站建设定制,农产品网站开发背景,无锡网站排名优化公司哪家好,新闻媒体发布平台Seata 是一款开源的分布式事务解决方案#xff0c;致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式#xff0c;为用户打造一站式的分布式解决方案 Seata 官网#xff1a;https://seata.io/zh-cn/ Spring Cloud Alibaba 官…Seata 是一款开源的分布式事务解决方案致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式为用户打造一站式的分布式解决方案 Seata 官网https://seata.io/zh-cn/ Spring Cloud Alibaba 官网https://sca.aliyun.com/zh-cn/   版本说明 SpringBoot 版本 2.6.5 SpringCloud 版本 2021.0.1 SpringCloudAlibaba 版本 2021.0.1.0 本文详细说明 数据库服务器版本 mysql 8.0.25 mybatis plus 版本 3.5.1 nacos 版本 1.4.2 seata 客户端版本 1.4.2 seata 服务端版本 1.7.1 本文讲解的是 seata 的 SAGA 事物模型在开始阅读下面内容之前建议先阅读笔者的这篇文章《Spring Cloud Alibaba Seata 实现分布式事物》这篇文章中实现的是 seata 的 AT 事物且笔者的本篇文章《Spring Cloud Alibaba Seata 实现 SAGA  事物》是在《Spring Cloud Alibaba Seata 实现分布式事物》基础上写的很多内容需要先了解涉及seata 和nacos的重复内容笔者在本篇文章中不在赘述因此建议读者先看《Spring Cloud Alibaba Seata 实现分布式事物》之后再学习本篇文章。当然如果你对 seata 的搭建已经非常熟悉那么可以直接开始下面阅读 Saga模式是SEATA提供的长事务解决方案在Saga模式中业务流程中每个参与者都提交本地事务当出现某一个参与者失败则补偿前面已经成功的参与者一阶段正向服务和二阶段补偿服务都由业务开发实现 Saga 文档https://seata.io/zh-cn/docs/user/saga 目录 1、创建项目 1.1、新建 maven 聚合项目 cloud-learn 1.2、创建 account 服务 1.3、创建 order 服务 2、添加配置 2.1、客户端配置 2.2、服务端配置 3、数据库建表 3.1、seata 服务端建表 3.2、seata 客户端建表 3.3、Saga 状态机建表 4、Saga 状态机 json 文件说明 5、运行测试 6、项目代码 1、创建项目 1.1、新建 maven 聚合项目 cloud-learn 最外层父工程 cloud-learn 的 pom.xml ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcom.wsjzzcbq/groupIdartifactIdcloud-learn/artifactIdversion1.0-SNAPSHOT/versionmodulesmodulegateway-learn/modulemoduleconsumer-learn/modulemodulesentinel-learn/modulemoduleseata-at-account-learn/modulemoduleseata-at-order-learn/modulemoduleseata-tcc-order-learn/modulemoduleseata-tcc-account-learn/modulemoduleseata-saga-account-learn/modulemoduleseata-saga-order-learn/module/modulespackagingpom/packagingrepositoriesrepositoryidnaxus-aliyun/idnamenaxus-aliyun/nameurlhttps://maven.aliyun.com/repository/public/urlreleasesenabledtrue/enabled/releasessnapshotsenabledfalse/enabled/snapshots/repository/repositoriesparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.6.5/versionrelativePath//parentpropertiesspring-cloud.version2021.0.1/spring-cloud.versionspring-cloud-alibaba.version2021.0.1.0/spring-cloud-alibaba.versionalibaba-nacos-discovery.veriosn2021.1/alibaba-nacos-discovery.veriosnalibaba-nacos-config.version2021.1/alibaba-nacos-config.versionspring-cloud-starter-bootstrap.version3.1.1/spring-cloud-starter-bootstrap.versiondruid.version1.1.17/druid.versionmysql.version8.0.11/mysql.versionmybatis-plus.version3.5.1/mybatis-plus.version/propertiesdependencyManagementdependenciesdependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-dependencies/artifactIdversion${spring-cloud.version}/versiontypepom/typescopeimport/scope/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-alibaba-dependencies/artifactIdversion${spring-cloud-alibaba.version}/versiontypepom/typescopeimport/scope/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactIdversion${alibaba-nacos-discovery.veriosn}/version/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-config/artifactIdversion${alibaba-nacos-config.version}/version/dependency!--spring-cloud-dependencies 2020.0.0 版本不在默认加载bootstrap文件如果需要加载bootstrap文件需要手动添加依赖--dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-bootstrap/artifactIdversion${spring-cloud-starter-bootstrap.version}/version/dependencydependencygroupIdcom.alibaba.fastjson2/groupIdartifactIdfastjson2/artifactIdversion2.0.40/version/dependency/dependencies/dependencyManagementdependenciesdependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependency/dependencies/project 下面会创建2个服务 account 和 order模拟用户下订单后扣减账户金额服务间使用 feign 调用因为 account 和 order 服务使用不同的数据库因此产生分布式事物使用 seata 解决 1.2、创建 account 服务 创建子工程 seata-saga-account-learn seata-saga-account-learn pom 文件 ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentartifactIdcloud-learn/artifactIdgroupIdcom.wsjzzcbq/groupIdversion1.0-SNAPSHOT/version/parentmodelVersion4.0.0/modelVersionartifactIdseata-saga-account-learn/artifactIddependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-config/artifactId/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-seata/artifactId/dependencydependencygroupIdcom.alibaba/groupIdartifactIddruid-spring-boot-starter/artifactIdversion${druid.version}/version/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion${mysql.version}/version/dependencydependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion${mybatis-plus.version}/version/dependency/dependenciesbuildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactId/plugin/plugins/build /project 启动类 SeataSAGAAccountApplication package com.wsjzzcbq;import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;/*** SeataSAGAAccountApplication** author wsjz* date 2023/10/24*/ MapperScan(value {com.wsjzzcbq.mapper}) SpringBootApplication public class SeataSAGAAccountApplication {public static void main(String[] args) {SpringApplication.run(SeataSAGAAccountApplication.class, args);} }实体类 Account package com.wsjzzcbq.bean;import lombok.Data;/*** Account** author wsjz* date 2022/07/07*/ Data public class Account {private Integer id;private String userId;private Integer money; }AccountMapper package com.wsjzzcbq.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.wsjzzcbq.bean.Account;/*** AccountMapper** author wsjz* date 2023/10/13*/ public interface AccountMapper extends BaseMapperAccount { }AccountService package com.wsjzzcbq.service;import com.baomidou.mybatisplus.extension.service.IService; import com.wsjzzcbq.bean.Account;/*** AccountService** author wsjz* date 2023/10/23*/ public interface AccountService extends IServiceAccount {boolean deductAccount(String userId, int money, boolean rollback);boolean compensateDeductAccount(String userId, int money); }AccountServiceImpl package com.wsjzzcbq.service.impl;import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.wsjzzcbq.bean.Account; import com.wsjzzcbq.mapper.AccountMapper; import com.wsjzzcbq.service.AccountService; import org.springframework.stereotype.Service;/*** AccountServiceImpl** author wsjz* date 2023/10/23*/ Service public class AccountServiceImpl extends ServiceImplAccountMapper, Account implements AccountService {Overridepublic boolean deductAccount(String userId, int money, boolean rollback) {System.out.println(扣减);UpdateWrapperAccount up new UpdateWrapper();String sql money money - money;up.setSql(sql);up.eq(user_id, userId);this.update(up);if (rollback) {int a 1/0;}return true;}Overridepublic boolean compensateDeductAccount(String userId, int money) {System.out.println(补偿);UpdateWrapperAccount up new UpdateWrapper();String sql money money money;up.setSql(sql);up.eq(user_id, userId);this.update(up);return true;} }AccountController package com.wsjzzcbq.controller;import com.wsjzzcbq.service.AccountService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;/*** AccountController** author wsjz* date 2023/10/23*/ RequestMapping(/account) RestController public class AccountController {Autowiredprivate AccountService accountService;GetMapping(/deduct)public boolean deductAccount(String userId, int money, boolean rollback) {return accountService.deductAccount(userId, money, rollback);}GetMapping(/compensate/deduct)public boolean compensateDeductAccount(String userId, int money) {return accountService.compensateDeductAccount(userId, money);} }application.yml 文件 server:port: 9001 spring:main:allow-circular-references: trueapplication:name: seata-saga-account-learndatasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.3.232:3306/pmc-account?useUnicodetruecharacterEncodingutf8autoReconnecttrueuseSSLfalseserverTimezoneAsia/Shanghaiusername: rootpassword: 123456cloud:nacos:username: nacospassword: nacosserver-addr: 192.168.2.140discovery:namespace: public # server-addr: 192.168.2.140 # config: # server-addr:seata:config:type: nacosnacos:server-addr: ${spring.cloud.nacos.server-addr}username: ${spring.cloud.nacos.username}password: ${spring.cloud.nacos.password}group: SEATA_GROUPdata-id: seata-saga.propertiesregistry:type: nacosnacos:application: seata-servercluster: defaultserver-addr: ${spring.cloud.nacos.server-addr}username: ${spring.cloud.nacos.username}password: ${spring.cloud.nacos.password}group: SEATA_GROUPenable-auto-data-source-proxy: falseclient:rm:report-success-enable: true # 事物分组如果不配置默认是spring.application.name -seata-service-group # tx-service-group:logging:level:com.wsjzzcbq.mapper: debug配置参数说明可以看《Spring Cloud Alibaba Seata 实现分布式事物》这里不再赘述 1.3、创建 order 服务 创建子工程 seata-saga-order-learn 项目 seata-saga-order-learn pom 文件 ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentartifactIdcloud-learn/artifactIdgroupIdcom.wsjzzcbq/groupIdversion1.0-SNAPSHOT/version/parentmodelVersion4.0.0/modelVersionartifactIdseata-saga-order-learn/artifactIddependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-config/artifactId/dependencydependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactId/dependencydependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-loadbalancer/artifactId/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-seata/artifactId/dependencydependencygroupIdcom.alibaba/groupIdartifactIddruid-spring-boot-starter/artifactIdversion${druid.version}/version/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion${mysql.version}/version/dependencydependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion${mybatis-plus.version}/version/dependency/dependenciesbuildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactId/plugin/plugins/build/project 启动类 SeataSAGAOrderApplication package com.wsjzzcbq;import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.openfeign.EnableFeignClients;/*** SeataSAGAOrderApplication** author wsjz* date 2023/10/24*/ MapperScan(value {com.wsjzzcbq.mapper}) EnableFeignClients SpringBootApplication public class SeataSAGAOrderApplication {public static void main(String[] args) {SpringApplication.run(SeataSAGAOrderApplication.class, args);} }订单实体类 Order package com.wsjzzcbq.bean;import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data;/*** Order** author wsjz* date 2022/07/07*/ TableName(order_tbl) Data public class Order {TableIdprivate Integer id;private String userId;private String code;private Integer count;private Integer money; }OrderMapper package com.wsjzzcbq.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.wsjzzcbq.bean.Order;/*** OrderMapper** author wsjz* date 2022/07/07*/ public interface OrderMapper extends BaseMapperOrder { }AccountFeign package com.wsjzzcbq.feign;import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam;/*** AccountFeign** author wsjz* date 2023/10/13*/ FeignClient(value seata-saga-account-learn) public interface AccountFeign {GetMapping(/account/deduct)boolean deductAccount(RequestParam(userId) String userId, RequestParam(money) int money, RequestParam(rollback) boolean rollback);GetMapping(/account/compensate/deduct)boolean compensateDeductAccount(RequestParam(userId) String userId, RequestParam(money) int money); }OrderService package com.wsjzzcbq.service;import com.baomidou.mybatisplus.extension.service.IService; import com.wsjzzcbq.bean.Order;/*** OrderService** author wsjz* date 2023/10/23*/ public interface OrderService extends IServiceOrder {boolean create(String orderCode, String userId, int money, int count, boolean rollback);boolean compensateCreate(String orderCode, String userId, int money); }OrderServiceImpl package com.wsjzzcbq.service.impl;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.wsjzzcbq.bean.Order; import com.wsjzzcbq.mapper.OrderMapper; import com.wsjzzcbq.service.OrderService; import org.springframework.stereotype.Service;/*** OrderServiceImpl** author wsjz* date 2023/10/23*/ Service(orderService) public class OrderServiceImpl extends ServiceImplOrderMapper, Order implements OrderService {Overridepublic boolean create(String orderCode, String userId, int money, int count, boolean rollback) {System.out.println(order下单);Order order new Order();order.setCode(orderCode);order.setUserId(userId);order.setMoney(money);order.setCount(count);this.save(order);// if (rollback) { // int a 1/0; // }return true;}Overridepublic boolean compensateCreate(String orderCode, String userId, int money) {System.out.println(order下单补偿);QueryWrapperOrder queryWrapper new QueryWrapper();queryWrapper.eq(code, orderCode);this.remove(queryWrapper);return true;} }saga基于状态机调用各个节点这里 seata-saga-order-learn 既是saga事物中的一个节点又是最外层的调用方笔者为了节省代码将调用方和order事物节点放在一起了 saga 事物 AccountService 节点调用 package com.wsjzzcbq.saga;/*** AccountService** author wsjz* date 2023/10/23*/ public interface AccountService {boolean deductAccount(String userId, int money, boolean rollback);boolean compensateDeductAccount(String userId, int money); }saga 事物 AccountService 节点实现类 AccountServiceImpl package com.wsjzzcbq.saga.impl;import com.wsjzzcbq.feign.AccountFeign; import com.wsjzzcbq.saga.AccountService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;/*** AccountServiceImpl** author wsjz* date 2023/10/23*/ Service(accountService) public class AccountServiceImpl implements AccountService {Autowiredprivate AccountFeign accountFeign;Overridepublic boolean deductAccount(String userId, int money, boolean rollback) {System.out.println(userId: userId : money money);try {return accountFeign.deductAccount(userId, money, rollback);} catch (Exception e) {throw new RuntimeException(e.getMessage());}}Overridepublic boolean compensateDeductAccount(String userId, int money) {System.out.println(userId: userId : money money);try {return accountFeign.compensateDeductAccount(userId, money);} catch (Exception e) {throw new RuntimeException(e.getMessage());}} }saga 状态机配置类 StateMachineEngineConfig package com.wsjzzcbq.config;import io.seata.saga.engine.config.DbStateMachineConfig; import io.seata.saga.engine.impl.ProcessCtrlStateMachineEngine; import io.seata.saga.rm.StateMachineEngineHolder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import javax.sql.DataSource; import java.util.concurrent.ThreadPoolExecutor;/*** StateMachineEngineConfig** author wsjz* date 2023/10/23*/ Configuration public class StateMachineEngineConfig {Autowiredprivate DataSource dataSource;Beanpublic ThreadPoolExecutor threadExecutor() {ThreadPoolTaskExecutor executor new ThreadPoolTaskExecutor();//核心线程数executor.setCorePoolSize(1);//最大线程数executor.setMaxPoolSize(20);//线程池中线程的名称前缀executor.setThreadNamePrefix(SAGA_ASYNC_EXE_);//初始化executor.initialize();return executor.getThreadPoolExecutor();}Beanpublic DbStateMachineConfig dbStateMachineConfig() {DbStateMachineConfig stateMachineConfig new DbStateMachineConfig();//设置saga状态机json文件路径stateMachineConfig.setDataSource(dataSource);ClassPathResource resource new ClassPathResource(seata/saga_order.json);stateMachineConfig.setResources(new Resource[]{resource});stateMachineConfig.setEnableAsync(true);stateMachineConfig.setThreadPoolExecutor(threadExecutor());//seata server服务名stateMachineConfig.setApplicationId(seata-server);//事物分组stateMachineConfig.setTxServiceGroup(seata-saga-account-learn-seata-service-group);return stateMachineConfig;}Beanpublic ProcessCtrlStateMachineEngine stateMachineEngine() {ProcessCtrlStateMachineEngine processCtrlStateMachineEngine new ProcessCtrlStateMachineEngine();processCtrlStateMachineEngine.setStateMachineConfig(dbStateMachineConfig());return processCtrlStateMachineEngine;}Beanpublic StateMachineEngineHolder stateMachineEngineHolder() {StateMachineEngineHolder engineHolder new StateMachineEngineHolder();engineHolder.setStateMachineEngine(stateMachineEngine());return engineHolder;} }OrderController package com.wsjzzcbq.controller;import io.seata.saga.engine.StateMachineEngine; import io.seata.saga.statelang.domain.ExecutionStatus; import io.seata.saga.statelang.domain.StateMachineInstance; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; import java.util.UUID;/*** OrderController** author wsjz* date 2023/10/23*/ RequestMapping(/order) RestController public class OrderController {Autowiredprivate StateMachineEngine stateMachineEngine;/*** http://localhost:9002/order/create?userId101money10count1rollbackfalse* param userId* param money* param count* param rollback* return*/RequestMapping(/create)public String create(String userId, int money, int count, boolean rollback) {String orderCode UUID.randomUUID().toString();MapString, Object startParams new HashMap();startParams.put(orderCode, orderCode);startParams.put(userId, userId);startParams.put(money, money);startParams.put(count, count);startParams.put(rollback, rollback);String businessKey String.valueOf(System.currentTimeMillis());StateMachineInstance stateMachineInstance stateMachineEngine.startWithBusinessKey(order, null, businessKey, startParams);if (ExecutionStatus.SU.equals(stateMachineInstance.getStatus())) {return 下单成功;} else {return 下单失败;}} }application.yml 文件 server:port: 9002 spring:main:allow-circular-references: trueapplication:name: seata-saga-order-learndatasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.3.232:3306/pmc-order?useUnicodetruecharacterEncodingutf8autoReconnecttrueuseSSLfalseserverTimezoneAsia/Shanghaiusername: rootpassword: 123456cloud:nacos:username: nacospassword: nacosserver-addr: 192.168.2.140discovery:namespace: public # server-addr: 192.168.2.140 # config: # server-addr:seata:config:type: nacosnacos:server-addr: ${spring.cloud.nacos.server-addr}username: ${spring.cloud.nacos.username}password: ${spring.cloud.nacos.password}group: SEATA_GROUPdata-id: seata-saga.propertiesregistry:type: nacosnacos:application: seata-servercluster: defaultserver-addr: ${spring.cloud.nacos.server-addr}username: ${spring.cloud.nacos.username}password: ${spring.cloud.nacos.password}group: SEATA_GROUP # 事物分组如果不配置默认是spring.application.name -seata-service-grouptx-service-group: seata-saga-account-learn-seata-service-groupenabled: trueclient:rm:report-success-enable: true # 是否开启数据源自动代理seata-spring-boot-starter专有配置默认会开启数据源自动代理可通过该配置项关闭enable-auto-data-source-proxy: falselogging:level:com.wsjzzcbq.mapper: debugmybatis-plus:global-config:db-config:id-type: auto saga 状态机 json 文件 在resources 目录下新建 seata 文件夹在seata 文件夹目录下新建 saga_order.json 文件 saga_order.json 文件内容 {nodes: [{type: node,size: 80*72,shape: flow-rhombus,color: #13C2C2,label: 订单服务结果选择,stateId: OrderService-create-Choice,stateType: Choice,x: 467.875,y: 286.5,id: c11238b3,stateProps: {Type: Choice,Choices: [{Expression: [deductResult] true,Next: AccountService-deductAccount}],Default: Fail},index: 6},{type: node,size: 39*39,shape: flow-circle,color: red,label: 账户服务异常捕获,stateId: AccountService-deductAccount-catch,stateType: Catch,x: 524.875,y: 431.5,id: 053ac3ac,index: 7},{type: node,size: 72*72,shape: flow-circle,color: #FA8C16,label: 开始,stateId: Start,stateType: Start,stateProps: {StateMachine: {Name: order,Comment: saga事物调用,Version: 0.0.1},Next: OrderService-create},x: 467.875,y: 53,id: 973bd79e,index: 11},{type: node,size: 110*48,shape: flow-rect,color: #1890FF,label: 订单服务,stateId: OrderService-create,stateType: ServiceTask,stateProps: {Type: ServiceTask,ServiceName: orderService,Next: AccountService-deduct-Choice,ServiceMethod: create,Input: [$.[orderCode],$.[userId],$.[money],$.[count],$.[rollback]],Output: {deductResult: $.#root},Status: {#root true: SU,#root false: FA,$Exception{java.lang.Throwable}: UN},CompensateState: OrderService-compensateCreate,Retry: []},x: 467.875,y: 172,id: e17372e4,index: 12},{type: node,size: 110*48,shape: flow-rect,color: #1890FF,label: 账户服务,stateId: AccountService-deductAccount,stateType: ServiceTask,stateProps: {Type: ServiceTask,ServiceName: accountService,ServiceMethod: deductAccount,CompensateState: AccountService-compensateDeductAccount,Input: [$.[userId],$.[money],$.[rollback]],Output: {deductResult: $.#root},Status: {#root true: SU,#root false: FA,$Exception{java.lang.Throwable}: UN},Next: Succeed},x: 467.125,y: 411,id: a6c40952,index: 13},{type: node,size: 110*48,shape: flow-capsule,color: #722ED1,label: 订单服务补偿,stateId: OrderService-compensateCreate,stateType: Compensation,stateProps: {Type: Compensation,ServiceName: orderService,ServiceMethod: compensateCreate,Input: [$.[orderCode],$.[userId],$.[money]]},x: 260.625,y: 172.5,id: 3b348652,index: 14},{type: node,size: 110*48,shape: flow-capsule,color: #722ED1,label: 账户服务补偿,stateId: AccountService-compensateDeductAccount,stateType: Compensation,stateProps: {Type: Compensation,ServiceName: accountService,ServiceMethod: compensateDeductAccount,Input: [$.[userId],$.[money],$.[rollback]]},x: 262.125,y: 411,id: 13b600b1,index: 15},{type: node,size: 72*72,shape: flow-circle,color: #05A465,label: 成功,stateId: Succeed,stateType: Succeed,x: 466.625,y: 597.5,id: 690e5c5e,stateProps: {Type: Succeed},index: 16},{type: node,size: 110*48,shape: flow-capsule,color: red,label: 补偿触发器,stateId: CompensationTrigger,stateType: CompensationTrigger,x: 894.125,y: 287,id: 757e057f,stateProps: {Type: CompensationTrigger,Next: Fail},index: 17},{type: node,size: 72*72,shape: flow-circle,color: red,label: 失败,stateId: Fail,stateType: Fail,stateProps: {Type: Fail,ErrorCode: FAILED,Message: buy failed},x: 684.125,y: 287,id: 0131fc0c,index: 18},{type: node,size: 39*39,shape: flow-circle,color: red,label: 订单服务异常捕获,stateId: OrderService-create-catch,stateType: Catch,x: 518.125,y: 183,id: 0955401d}],edges: [{source: 973bd79e,sourceAnchor: 2,target: e17372e4,targetAnchor: 0,id: f0a9008f,index: 0},{source: e17372e4,sourceAnchor: 2,target: c11238b3,targetAnchor: 0,id: cd8c3104,index: 2,label: 执行结果,shape: flow-smooth},{source: c11238b3,sourceAnchor: 2,target: a6c40952,targetAnchor: 0,id: e47e49bc,stateProps: {},label: 执行成功,shape: flow-smooth,index: 3},{source: c11238b3,sourceAnchor: 1,target: 0131fc0c,targetAnchor: 3,id: e3f9e775,stateProps: {},label: 执行失败,shape: flow-smooth,index: 4},{source: 053ac3ac,sourceAnchor: 1,target: 757e057f,targetAnchor: 2,id: 3f7fe6ad,stateProps: {Exceptions: [java.lang.Throwable],Next: CompensationTrigger},label: 账户服务异常触发补偿,shape: flow-polyline-round,index: 5},{source: e17372e4,sourceAnchor: 3,target: 3b348652,targetAnchor: 1,id: 52a2256e,style: {lineDash: 4},index: 8,label: ,shape: flow-smooth},{source: a6c40952,sourceAnchor: 3,target: 13b600b1,targetAnchor: 1,id: 474512d9,style: {lineDash: 4},index: 9},{source: 0955401d,sourceAnchor: 1,target: 757e057f,targetAnchor: 0,id: 654280aa,shape: flow-polyline-round,stateProps: {Exceptions: [java.lang.Throwable],Next: CompensationTrigger},label: 订单服务异常触发补偿},{source: a6c40952,sourceAnchor: 2,target: 690e5c5e,targetAnchor: 0,id: b6bd2f2a,shape: flow-polyline-round},{source: 757e057f,sourceAnchor: 3,target: 0131fc0c,targetAnchor: 1,id: 7ad2f2b9,shape: flow-polyline-round}] } 2、添加配置 2.1、客户端配置 在nacos上新建 group 是 SEATA_GROUPdata-id 是 seata-saga.properties 的配置内容如下 seata-saga.properties #For details about configuration items, see https://seata.io/zh-cn/docs/user/configurations.html #Transport configuration, for client and server transport.typeTCP transport.serverNIO transport.heartbeattrue transport.enableTmClientBatchSendRequestfalse transport.enableRmClientBatchSendRequesttrue transport.enableTcServerBatchSendResponsefalse transport.rpcRmRequestTimeout30000 transport.rpcTmRequestTimeout30000 transport.rpcTcRequestTimeout30000 transport.threadFactory.bossThreadPrefixNettyBoss transport.threadFactory.workerThreadPrefixNettyServerNIOWorker transport.threadFactory.serverExecutorThreadPrefixNettyServerBizHandler transport.threadFactory.shareBossWorkerfalse transport.threadFactory.clientSelectorThreadPrefixNettyClientSelector transport.threadFactory.clientSelectorThreadSize1 transport.threadFactory.clientWorkerThreadPrefixNettyClientWorkerThread transport.threadFactory.bossThreadSize1 transport.threadFactory.workerThreadSizedefault transport.shutdown.wait3 transport.serializationseata transport.compressornone#Transaction routing rules configuration, only for the client service.vgroupMapping.seata-saga-account-learn-seata-service-groupdefault #If you use a registry, you can ignore it service.default.grouplist127.0.0.1:8091 service.enableDegradefalse service.disableGlobalTransactionfalse#Transaction rule configuration, only for the client client.rm.asyncCommitBufferLimit10000 client.rm.lock.retryInterval10 client.rm.lock.retryTimes30 client.rm.lock.retryPolicyBranchRollbackOnConflicttrue client.rm.reportRetryCount5 client.rm.tableMetaCheckEnabletrue client.rm.tableMetaCheckerInterval60000 client.rm.sqlParserTypedruid client.rm.reportSuccessEnablefalse client.rm.sagaBranchRegisterEnablefalse client.rm.sagaJsonParserfastjson client.rm.tccActionInterceptorOrder-2147482648 client.tm.commitRetryCount5 client.tm.rollbackRetryCount5 client.tm.defaultGlobalTransactionTimeout60000 client.tm.degradeCheckfalse client.tm.degradeCheckAllowTimes10 client.tm.degradeCheckPeriod2000 client.tm.interceptorOrder-2147482648 client.undo.dataValidationtrue client.undo.logSerializationjackson client.undo.onlyCareUpdateColumnstrue server.undo.logSaveDays7 server.undo.logDeletePeriod86400000 client.undo.logTableundo_log client.undo.compress.enabletrue client.undo.compress.typezip client.undo.compress.threshold64k #For TCC transaction mode tcc.fence.logTableNametcc_fence_log tcc.fence.cleanPeriod1h # You can choose from the following options: fastjson, jackson, gson tcc.contextJsonParserTypefastjson#Log rule configuration, for client and server log.exceptionRate100 seata-saga.properties 在《Spring Cloud Alibaba Seata 实现分布式事物》的 seata.properties 基础上修改事物分组即可 2.2、服务端配置 服务端配置和《Spring Cloud Alibaba Seata 实现分布式事物》保持一致无需修改 3、数据库建表 3.1、seata 服务端建表 看《Spring Cloud Alibaba Seata 实现分布式事物》seata 服务端建表保持一致无需修改 3.2、seata 客户端建表 看《Spring Cloud Alibaba Seata 实现分布式事物》seata 客户端建表 undo_log 表不需要保留 account 和 order_tbl 表即可 3.3、Saga 状态机建表 Saga 状态机表和最外层调用方在同一个库在笔者的项目中和 order服务的库放在一起 建表 sql 在 seata 源码 seata\script\client\saga\db 目录下 建表sql -- -------------------------------- The script used for sage --------------------------------CREATE TABLE IF NOT EXISTS seata_state_machine_def (id VARCHAR(32) NOT NULL COMMENT id,name VARCHAR(128) NOT NULL COMMENT name,tenant_id VARCHAR(32) NOT NULL COMMENT tenant id,app_name VARCHAR(32) NOT NULL COMMENT application name,type VARCHAR(20) COMMENT state language type,comment_ VARCHAR(255) COMMENT comment,ver VARCHAR(16) NOT NULL COMMENT version,gmt_create DATETIME(3) NOT NULL COMMENT create time,status VARCHAR(2) NOT NULL COMMENT status(AC:active|IN:inactive),content TEXT COMMENT content,recover_strategy VARCHAR(16) COMMENT transaction recover strategy(compensate|retry),PRIMARY KEY (id) ) ENGINE InnoDBDEFAULT CHARSET utf8mb4;CREATE TABLE IF NOT EXISTS seata_state_machine_inst (id VARCHAR(128) NOT NULL COMMENT id,machine_id VARCHAR(32) NOT NULL COMMENT state machine definition id,tenant_id VARCHAR(32) NOT NULL COMMENT tenant id,parent_id VARCHAR(128) COMMENT parent id,gmt_started DATETIME(3) NOT NULL COMMENT start time,business_key VARCHAR(48) COMMENT business key,start_params TEXT COMMENT start parameters,gmt_end DATETIME(3) COMMENT end time,excep BLOB COMMENT exception,end_params TEXT COMMENT end parameters,status VARCHAR(2) COMMENT status(SU succeed|FA failed|UN unknown|SK skipped|RU running),compensation_status VARCHAR(2) COMMENT compensation status(SU succeed|FA failed|UN unknown|SK skipped|RU running),is_running TINYINT(1) COMMENT is running(0 no|1 yes),gmt_updated DATETIME(3) NOT NULL,PRIMARY KEY (id),UNIQUE KEY unikey_buz_tenant (business_key, tenant_id) ) ENGINE InnoDBDEFAULT CHARSET utf8mb4;CREATE TABLE IF NOT EXISTS seata_state_inst (id VARCHAR(48) NOT NULL COMMENT id,machine_inst_id VARCHAR(128) NOT NULL COMMENT state machine instance id,name VARCHAR(128) NOT NULL COMMENT state name,type VARCHAR(20) COMMENT state type,service_name VARCHAR(128) COMMENT service name,service_method VARCHAR(128) COMMENT method name,service_type VARCHAR(16) COMMENT service type,business_key VARCHAR(48) COMMENT business key,state_id_compensated_for VARCHAR(50) COMMENT state compensated for,state_id_retried_for VARCHAR(50) COMMENT state retried for,gmt_started DATETIME(3) NOT NULL COMMENT start time,is_for_update TINYINT(1) COMMENT is service for update,input_params TEXT COMMENT input parameters,output_params TEXT COMMENT output parameters,status VARCHAR(2) NOT NULL COMMENT status(SU succeed|FA failed|UN unknown|SK skipped|RU running),excep BLOB COMMENT exception,gmt_updated DATETIME(3) COMMENT update time,gmt_end DATETIME(3) COMMENT end time,PRIMARY KEY (id, machine_inst_id) ) ENGINE InnoDBDEFAULT CHARSET utf8mb4; 在order服务 pmc-order 库中 4、Saga 状态机 json 文件说明 笔者使用的 seata-server 版本是 1.7.1可以直接打开 http://localhost:7091/ seata 控制台里面有Saga 状态机设计器可以拖拽编辑状态机文件。如果是较低版本的 seata server需要在seata源码中找到 seata-saga-statemachine-designer 项目npm install 安装依赖npm run start 运行项目这个seata-saga-statemachine-designer 是一个单独的Saga 状态机设计器和seata-server -1.7.1 控制台中的一样 将笔者的 saga_order.json 文件复制到状态机设计器中可查看saga事物调用流程 这个流程图定义了saga事物流程 Next指向下一步执行的节点 ServiceName 对应代码中spring的bean名称即 seata-saga-order-learn 中 OrderServiceImplOrderServiceImpl 类上面标记注解 Service(orderService) ServiceMethod 对应的是 ServiceName下的方法名 Input 是ServiceMethod 方法的参数 Output 是ServiceMethod 方法返回值赋给变量 deductResult Status 是服务执行状态SU 成功、FA 失败、UN 未知。我们需要把程序执行结果转换成这个3个状态程序返回true对应 SUfalse 对应FA抛出异常是UN CompensateState 是补偿写补偿节点的 id ServiceName 、 ServiceMethod 和 Input 道理同上发生补偿时触发补偿的方法 捕获异常触发补偿 补偿触发器 程序执行结果判断 Expression 判断程序执行结果 Next 指向下一节点 更多seata内容可以看官网文档https://seata.io/zh-cn/docs/user/saga 5、运行测试 启动 seata-server-1.7.1 进入 bin 目录双击 seata-server.bat 启动 account 和 order 服务 nacos 服务和配置 测试正常情况 浏览器请求http://localhost:9002/order/create?userId101money10rollbackfalse 扣减账户 10 元新增订单 测试回滚情况 6、项目代码 码云地址https://gitee.com/wsjzzcbq/csdn-blog/tree/master/cloud-learn 至此完
http://www.hkea.cn/news/14449153/

相关文章:

  • 个人怎么做贷款网站网站恶意刷
  • 网站开发要注意安全性营销网站建设与推广方案
  • 信息门户网站制作wordpress博客优化
  • 个人网站备案名字大全网页怎么做出来的
  • 二级建造师考试科目天津百度seo
  • 南安市建设局网站ui设计是怎么实现的
  • 网站域名是不是网址公司的英文网站
  • 全国有哪些做服装的网站西安短视频制作
  • app网站建设方案网站制作公司源码
  • 自己怎么优化我网站关键词装门做特卖的网站
  • 龙华app网站制作哈尔滨网站建设费用
  • wap网站优化wordpress添加商品分类页
  • 网站建设 cn福州网站建设嘉艺
  • 《网站开发实例》pdf下载WordPress百度收录代码
  • 可做区域代理的网站e福州app官方下载
  • 网络网站制作技巧潍坊网站开发招生信息
  • 网站建设收费标准不一兰州网站优化
  • 做网站销售好吗seo主要做什么工作内容
  • 重庆 做网站惠州网站开发公司
  • 公司网站建设策划方案低价企业网站搭建
  • 网站搜索引擎优化方案论文jsp sql 网站开发
  • 清远手机网站建设重庆网站推广外包
  • 自己做淘宝客网站apache怎么配置网站
  • 私人订制网站的建设的设计表php网站开发招聘
  • 界面做的比较好的网站德吉机械东莞网站建设
  • 貴阳建设银行网站网页设计个人网页html代码
  • 移动端的网站模板dw个人网站制作
  • 白云区专业网站建设外包项目网站
  • 网站名称注意事项荔枝fm入口
  • 海西州电子商务网站建设公司WordPress文章归档错误