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

wordpress 实战视频教程家庭优化大师下载

wordpress 实战视频教程,家庭优化大师下载,男人与女人做视频网站,北京微信网站Seata 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。 官网:Apache Seata 文章目录 一、部署1.下载2.修改配置,nacos作注册中心,db存储 二、集成到springcloud项目1.引入依赖2.修改…

Seata 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。

官网:Apache Seata

文章目录

  • 一、部署
    • 1.下载
    • 2.修改配置,nacos作注册中心,db存储
  • 二、集成到springcloud项目
    • 1.引入依赖
    • 2.修改配置
    • 3.新建数据表
    • 4.编写代码
    • 5.测试结果

一、部署

由于网络问题一直拉取docker镜像失败,所以这里采用了下载zip包直接部署的方式

版本说明 · alibaba/spring-cloud-alibaba Wiki · GitHub (需要和springcloud的版本对应)

1.下载

直接部署 | Apache Seata

上传服务器并解压

在这里插入图片描述

2.修改配置,nacos作注册中心,db存储

修改conf/application.yml

server:port: 7091spring:application:name: seata-serverlogging:config: classpath:logback-spring.xmlfile:path: ${user.home}/logs/seataextend:logstash-appender:destination: 192.168.100.52:4560kafka-appender:bootstrap-servers: 192.168.100.52:9092topic: logback_to_logstashconsole:user:username: seatapassword: seataseata:config:# support: nacos, consul, apollo, zk, etcd3type: nacosnacos:server-addr: 192.168.100.53:8848namespace: 17a4ea5e-f549-4e4a-97a4-52ee2a9f466cgroup: spmp-systemusername: nacospassword: nacosdata-id: seataServer.propertiesregistry:# support: nacos, eureka, redis, zk, consul, etcd3, sofatype: nacosnacos:application: seata-serverserver-addr: 192.168.100.53:8848group: spmp-systemnamespace: 17a4ea5e-f549-4e4a-97a4-52ee2a9f466c# tc集群名称cluster: defaultusername: nacospassword: nacos
#  server:
#    service-port: 8091 #If not configured, the default is '${server.port} + 1000'security:secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017tokenValidityInMilliseconds: 1800000ignore:urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/api/v1/auth/login

此时启动seata服务端,已经可以在nacos服务列表看到seata-server服务

cd bin
sh seata-seaver.sh

在这里插入图片描述

然后在nacos新建配置文件seataServer.properties

在这里插入图片描述

store.mode=db
store.db.dbType=mysql
store.db.datasource=druid
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql://192.168.100.52:3306/seata?characterEncoding=UTF8&autoReconnect=true&serverTimezone=Asia/Shanghai
store.db.user=seata
store.db.password=seata

这里注意先建数据库seata,然后执行建表sql,脚本在script/server/db/下的mysql.sql

在这里插入图片描述

然后重启seata服务端

可以从seata启动日志 logs/start.out 看到读取配置的相关信息

在这里插入图片描述

二、集成到springcloud项目

这里我们拿项目里其中两个微服务来测试,如图所示,服务1被调用方服务2调用方

在这里插入图片描述

1.引入依赖

两个微服务的pom文件里都需要引入seata依赖

<dependency><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId><version>1.6.1</version>
</dependency>
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId><version>2021.0.5.0</version><exclusions><exclusion><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId></exclusion></exclusions>
</dependency>

2.修改配置

修改两个微服务的配置文件,这里对应上前面seata服务端的配置

seata:registry:type: nacosnacos:application: seata-serverserver-addr: 192.168.100.53:8848group: spmp-systemnamespace: 17a4ea5e-f549-4e4a-97a4-52ee2a9f466cusername: nacospassword: nacosconfig:type: nacosnacos:server-addr: 192.168.100.53:8848group: spmp-systemnamespace: 17a4ea5e-f549-4e4a-97a4-52ee2a9f466cdataId: seataServer.propertiesusername: nacospassword: nacostx-service-group: spmp-system

3.新建数据表

两个服务都需要新建undo_log表,在事务回滚时需要用到,建表sql:

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;

4.编写代码

  • 修改全局异常处理器GlobalExceptionHandler

    由于项目里的全局处理器通常都会将所有异常拦截,然后返回统一封装结果,而这会导致异常无法抛出

    /*** 全局异常处理器** @author ruoyi*/
    @RestControllerAdvice
    public class GlobalExceptionHandler {private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);/*** 先判断是否是seata全局事务异常,如果是,就直接抛给调用方,让调用方回滚事务* @param e* @throws Exception*/private void checkSeataError(Exception e) throws Exception {log.info("seata全局事务ID: {}", RootContext.getXID());// 如果是在一次全局事务里出异常了,就不要包装返回值,将异常抛给调用方,让调用方回滚事务if (StrUtil.isNotBlank(RootContext.getXID())) {throw e;}}/*** 请求方式不支持*/@ExceptionHandler(HttpRequestMethodNotSupportedException.class)public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, HttpServletRequest request) throws Exception {checkSeataError(e);String requestUri = request.getRequestURI();log.error("请求地址'{}',不支持'{}'请求", requestUri, e.getMethod());return AjaxResult.error(e.getMessage());}/*** 业务异常*/@ExceptionHandler(ServiceException.class)public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request) throws Exception {checkSeataError(e);log.error(e.getMessage(), e);Integer code = e.getCode();return StringUtils.isNotNull(code) ? AjaxResult.error(code, StrUtil.isEmpty(e.getMessage()) ? e.getCause().getMessage() : e.getMessage()) : AjaxResult.error(StrUtil.isEmpty(e.getMessage()) ? e.getCause().getMessage() : e.getMessage());}/*** 请求参数类型不匹配*/@ExceptionHandler(MethodArgumentTypeMismatchException.class)public AjaxResult handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request) throws Exception {checkSeataError(e);String requestUri = request.getRequestURI();String value = Convert.toStr(e.getValue());if (StringUtils.isNotEmpty(value)) {value = EscapeUtil.clean(value);}log.error("请求参数类型不匹配'{}',发生系统异常.", requestUri, e);return AjaxResult.error(String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'", e.getName(), e.getRequiredType().getName(), value));}/*** 切面异常统一捕获*/@ExceptionHandler(AspectException.class)public ResponseResult<?> handleAspectException(AspectException aspectException) {aspectException.printStackTrace();return ResponseResult.error(aspectException.getResultStatus(), null);}/*** 系统基类异常捕获*/@ExceptionHandler(BasesException.class)public ResponseResult<?> handleBasesException(BasesException basesException) throws Exception {checkSeataError(basesException);basesException.printStackTrace();return ResponseResult.error(basesException.getResultStatus(), null);}/*** 拦截未知的运行时异常*/@ExceptionHandler(RuntimeException.class)public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request) throws Exception {checkSeataError(e);String requestUri = request.getRequestURI();log.error("请求地址'{}',发生未知异常.", requestUri, e);return AjaxResult.error(e.getMessage());}/*** 系统异常*/@ExceptionHandler(Exception.class)public AjaxResult handleException(Exception e, HttpServletRequest request) throws Exception {checkSeataError(e);String requestUri = request.getRequestURI();log.error("请求地址'{}',发生系统异常.", requestUri, e);return AjaxResult.error(e.getMessage());}/*** 自定义验证异常*/@ExceptionHandler(BindException.class)public AjaxResult handleBindException(BindException e) throws Exception {checkSeataError(e);log.error(e.getMessage(), e);String message = e.getAllErrors().get(0).getDefaultMessage();return AjaxResult.error(message);}/*** 自定义验证异常*/@ExceptionHandler(MethodArgumentNotValidException.class)public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) throws Exception {checkSeataError(e);log.error(e.getMessage(), e);String message = e.getBindingResult().getFieldError().getDefaultMessage();return ResponseResult.error(message);}/*** 内部认证异常*/@ExceptionHandler(InnerAuthException.class)public AjaxResult handleInnerAuthException(InnerAuthException e) throws Exception {checkSeataError(e);return AjaxResult.error(e.getMessage());}......
    }
    
  • 修改Feign熔断降级方法

    由于项目对远程调用接口还做了熔断降级操作,导致调用方仍然识别不到异常,所以这里将熔断降级方法修改下,让其能正常抛异常

    @Component
    @Slf4j
    public class ConstructionProviderFallback implements IConstructionProvider {@Overridepublic ResponseResult<String> testSeata(Boolean error) {if (error) {throw new RuntimeException("降级方法中---模拟被调用方异常");}return ResponseResult.success("----------------testSeata接口远程调用熔断-----------------");}
    }
    
  • 启动类增加AOP注解

    由于全局事务注解@GlobalTransactional底层是基于AOP实现,所以需要给两个服务的启动类都加上AOP注解

    @EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)

  • 调用方测试接口

    /*** 测试全局事务* @return*/
    @ApiOperation("测试全局事务")
    @GetMapping("/testSeata")
    @ApiImplicitParam(name = "type", value = "1:模拟调用方异常 其他:模拟被调用方异常")
    public ResponseResult<Boolean> testSeata(@RequestParam Integer type) {SecurityTest securityTest = new SecurityTest();securityTest.setTestColumn("测试全局事务");securityTest.setOrganizeId(1L);return ResponseResult.success(testSeataService.testSeata(type,securityTest));
    }
    
    @GlobalTransactional
    @Override
    public Boolean testSeata(Integer type, SecurityTest securityTest) {log.info("seata全局事务ID: {}", RootContext.getXID());if (type!=null&&type==1) {//先远程调用construction服务保存远程服务数据constructionProvider.testSeata(false);//再保存自己服务数据securityTestService.save(securityTest);//模拟调用方异常throw new RuntimeException("模拟调用方异常");} else {//先保存自己服务数据securityTestService.save(securityTest);//再远程调用construction服务保存远程服务数据,且模拟被调用方异常constructionProvider.testSeata(true);}return true;
    }
    

    这里测试两种情况,调用方异常事务回滚,还有被调用方异常事务回滚

  • 被调用方提供的Feign接口

    @Service(value = "IConstructionProvider")
    @FeignClient(value = ConstructionProviderConstant.MATE_CLOUD_CONSTRUCTION, fallback = ConstructionProviderFallback.class)
    public interface IConstructionProvider {/*** 测试全局事务* @param error* @return*/@GetMapping(ConstructionProviderConstant.TEST_SEATA)ResponseResult<String> testSeata(@RequestParam("error") Boolean error);}
    

    这里当时遇到了一个坑

    • 如果不写@RequestParam(“error”) ,会识别成POST请求,然后报错不支持POST请求

    • 如果写了@RequestParam,但是没设置value属性,即写@RequestParam Boolean error,也会报错

      参考:Feign 调用报 RequestParam.value() was empty on parameter 0-CSDN博客

    实现:

    在这里插入图片描述

    正常调用:

    /*** 测试Seata全局事务* @param error 是否模拟被调用方异常* @return*/
    @Override
    @ApiOperation(value = "测试Seata全局事务", notes = "测试Seata全局事务", httpMethod = "GET")
    @GetMapping(ConstructionProviderConstant.TEST_SEATA)
    @SentinelResource(value = ConstructionProviderConstant.TEST_SEATA, fallbackClass = ConstructionProviderFallback.class, fallback = "testFeign")
    public ResponseResult<String> testSeata(@RequestParam(value = "error") Boolean error) {SecurityTest1 test = new SecurityTest1();test.setTestColumn("seata");test.setOrganizeId(1L);securityTestService.save(test);if (error) {throw new RuntimeException("模拟被调用方异常");}return ResponseResult.success("---------------testSeata接口正常------------------");
    }
    

    熔断降级:

    @Override
    public ResponseResult<String> testSeata(Boolean error) {if (error) {throw new RuntimeException("降级方法中---模拟被调用方异常");}return ResponseResult.success("----------------testSeata接口远程调用熔断-----------------");
    }
    

5.测试结果

分别测试了调用方异常、被调用方异常的情况,均能实现全局事务回滚(两边的数据库都回滚了),如下图所示

在这里插入图片描述

在这里插入图片描述

下面是seata控制台的信息(存于数据库里)

在这里插入图片描述

这里我测试的结果是 只有调用方和被调用方都有事务回滚 才会有信息,而且会定期清除

http://www.hengruixuexiao.com/news/13951.html

相关文章:

  • 做网站做生意国家免费培训网站
  • 马鞍山网站建设设计网络营销的企业有哪些
  • 网站开发立项报告福州百度快速优化
  • php做的网站怎么上传seo咨询服务价格
  • 做网站做系统数字营销公司排行榜
  • 网站做301根目录在哪湖南网站seo推广
  • 做淘客必须有自己内部网站吗免费网络推广渠道
  • 南京价格网站建设门户网站建站系统
  • asp网站知道用户名是admin十大营销手段
  • 交互网站图怎样推广小程序平台
  • 最好的设计公司seo前景
  • 原创wordpress付费主题seo文章排名优化
  • wordpress4.9.8主题重庆seo怎么样
  • 建网站和建小程序多少钱昆明装饰企业网络推广
  • 如何做网站好看做网络营销推广
  • 运城网络推广北京seo公司哪家好
  • 网站规划与网站建设地推拉新app推广平台
  • wordpress企业培训seo基础
  • 怎么给甲方做网站备案新闻最近的新闻
  • 设计 p网站泉州seo优化
  • 不带www的网站2024年3月份病毒会爆发吗
  • 焦作市住房和城乡建设局网站百度站长工具app
  • 扫码点餐微信小程序怎么样开通搜索引擎优化百度
  • 中国100强排名企业名单郑州seo优化顾问
  • 潍坊网站开发高手推广联盟平台
  • 网站接入支付宝在线交易怎么做北京百度科技有限公司电话
  • 免费1级做看网站seo计费系统
  • 网站名称 规则站优化
  • 微信公众号优惠和网站绑定怎么做厦门谷歌seo公司
  • 做网站含营销郑州seo