国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁(yè) > news >正文

品牌展板設(shè)計(jì)制作seo免費(fèi)軟件

品牌展板設(shè)計(jì)制作,seo免費(fèi)軟件,四川招標(biāo)采購(gòu)信息網(wǎng)官網(wǎng),西安網(wǎng)站建設(shè)設(shè)計(jì)的好公司Seata 是一款開(kāi)源的分布式事務(wù)解決方案,致力于在微服務(wù)架構(gòu)下提供高性能和簡(jiǎn)單易用的分布式事務(wù)服務(wù)。 官網(wǎng):Apache Seata 文章目錄 一、部署1.下載2.修改配置,nacos作注冊(cè)中心,db存儲(chǔ) 二、集成到springcloud項(xiàng)目1.引入依賴2.修改…

Seata 是一款開(kāi)源的分布式事務(wù)解決方案,致力于在微服務(wù)架構(gòu)下提供高性能和簡(jiǎn)單易用的分布式事務(wù)服務(wù)。

官網(wǎng):Apache Seata

文章目錄

  • 一、部署
    • 1.下載
    • 2.修改配置,nacos作注冊(cè)中心,db存儲(chǔ)
  • 二、集成到springcloud項(xiàng)目
    • 1.引入依賴
    • 2.修改配置
    • 3.新建數(shù)據(jù)表
    • 4.編寫代碼
    • 5.測(cè)試結(jié)果

一、部署

由于網(wǎng)絡(luò)問(wèn)題一直拉取docker鏡像失敗,所以這里采用了下載zip包直接部署的方式

版本說(shuō)明 · alibaba/spring-cloud-alibaba Wiki · GitHub (需要和springcloud的版本對(duì)應(yīng))

1.下載

直接部署 | Apache Seata

上傳服務(wù)器并解壓

在這里插入圖片描述

2.修改配置,nacos作注冊(cè)中心,db存儲(chǔ)

修改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

此時(shí)啟動(dòng)seata服務(wù)端,已經(jīng)可以在nacos服務(wù)列表看到seata-server服務(wù)

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

這里注意先建數(shù)據(jù)庫(kù)seata,然后執(zhí)行建表sql,腳本在script/server/db/下的mysql.sql

在這里插入圖片描述

然后重啟seata服務(wù)端

可以從seata啟動(dòng)日志 logs/start.out 看到讀取配置的相關(guān)信息

在這里插入圖片描述

二、集成到springcloud項(xiàng)目

這里我們拿項(xiàng)目里其中兩個(gè)微服務(wù)來(lái)測(cè)試,如圖所示,服務(wù)1被調(diào)用方服務(wù)2調(diào)用方

在這里插入圖片描述

1.引入依賴

兩個(gè)微服務(wù)的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.修改配置

修改兩個(gè)微服務(wù)的配置文件,這里對(duì)應(yīng)上前面seata服務(wù)端的配置

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.新建數(shù)據(jù)表

兩個(gè)服務(wù)都需要新建undo_log表,在事務(wù)回滾時(shí)需要用到,建表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

    由于項(xiàng)目里的全局處理器通常都會(huì)將所有異常攔截,然后返回統(tǒng)一封裝結(jié)果,而這會(huì)導(dǎo)致異常無(wú)法拋出

    /*** 全局異常處理器** @author ruoyi*/
    @RestControllerAdvice
    public class GlobalExceptionHandler {private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);/*** 先判斷是否是seata全局事務(wù)異常,如果是,就直接拋給調(diào)用方,讓調(diào)用方回滾事務(wù)* @param e* @throws Exception*/private void checkSeataError(Exception e) throws Exception {log.info("seata全局事務(wù)ID: {}", RootContext.getXID());// 如果是在一次全局事務(wù)里出異常了,就不要包裝返回值,將異常拋給調(diào)用方,讓調(diào)用方回滾事務(wù)if (StrUtil.isNotBlank(RootContext.getXID())) {throw e;}}/*** 請(qǐng)求方式不支持*/@ExceptionHandler(HttpRequestMethodNotSupportedException.class)public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, HttpServletRequest request) throws Exception {checkSeataError(e);String requestUri = request.getRequestURI();log.error("請(qǐng)求地址'{}',不支持'{}'請(qǐng)求", requestUri, e.getMethod());return AjaxResult.error(e.getMessage());}/*** 業(yè)務(wù)異常*/@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());}/*** 請(qǐng)求參數(shù)類型不匹配*/@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("請(qǐng)求參數(shù)類型不匹配'{}',發(fā)生系統(tǒng)異常.", requestUri, e);return AjaxResult.error(String.format("請(qǐng)求參數(shù)類型不匹配,參數(shù)[%s]要求類型為:'%s',但輸入值為:'%s'", e.getName(), e.getRequiredType().getName(), value));}/*** 切面異常統(tǒng)一捕獲*/@ExceptionHandler(AspectException.class)public ResponseResult<?> handleAspectException(AspectException aspectException) {aspectException.printStackTrace();return ResponseResult.error(aspectException.getResultStatus(), null);}/*** 系統(tǒng)基類異常捕獲*/@ExceptionHandler(BasesException.class)public ResponseResult<?> handleBasesException(BasesException basesException) throws Exception {checkSeataError(basesException);basesException.printStackTrace();return ResponseResult.error(basesException.getResultStatus(), null);}/*** 攔截未知的運(yùn)行時(shí)異常*/@ExceptionHandler(RuntimeException.class)public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request) throws Exception {checkSeataError(e);String requestUri = request.getRequestURI();log.error("請(qǐng)求地址'{}',發(fā)生未知異常.", requestUri, e);return AjaxResult.error(e.getMessage());}/*** 系統(tǒng)異常*/@ExceptionHandler(Exception.class)public AjaxResult handleException(Exception e, HttpServletRequest request) throws Exception {checkSeataError(e);String requestUri = request.getRequestURI();log.error("請(qǐng)求地址'{}',發(fā)生系統(tǒng)異常.", requestUri, e);return AjaxResult.error(e.getMessage());}/*** 自定義驗(yàn)證異常*/@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);}/*** 自定義驗(yàn)證異常*/@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);}/*** 內(nèi)部認(rèn)證異常*/@ExceptionHandler(InnerAuthException.class)public AjaxResult handleInnerAuthException(InnerAuthException e) throws Exception {checkSeataError(e);return AjaxResult.error(e.getMessage());}......
    }
    
  • 修改Feign熔斷降級(jí)方法

    由于項(xiàng)目對(duì)遠(yuǎn)程調(diào)用接口還做了熔斷降級(jí)操作,導(dǎo)致調(diào)用方仍然識(shí)別不到異常,所以這里將熔斷降級(jí)方法修改下,讓其能正常拋異常

    @Component
    @Slf4j
    public class ConstructionProviderFallback implements IConstructionProvider {@Overridepublic ResponseResult<String> testSeata(Boolean error) {if (error) {throw new RuntimeException("降級(jí)方法中---模擬被調(diào)用方異常");}return ResponseResult.success("----------------testSeata接口遠(yuǎn)程調(diào)用熔斷-----------------");}
    }
    
  • 啟動(dòng)類增加AOP注解

    由于全局事務(wù)注解@GlobalTransactional底層是基于AOP實(shí)現(xiàn),所以需要給兩個(gè)服務(wù)的啟動(dòng)類都加上AOP注解

    @EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)

  • 調(diào)用方測(cè)試接口

    /*** 測(cè)試全局事務(wù)* @return*/
    @ApiOperation("測(cè)試全局事務(wù)")
    @GetMapping("/testSeata")
    @ApiImplicitParam(name = "type", value = "1:模擬調(diào)用方異常 其他:模擬被調(diào)用方異常")
    public ResponseResult<Boolean> testSeata(@RequestParam Integer type) {SecurityTest securityTest = new SecurityTest();securityTest.setTestColumn("測(cè)試全局事務(wù)");securityTest.setOrganizeId(1L);return ResponseResult.success(testSeataService.testSeata(type,securityTest));
    }
    
    @GlobalTransactional
    @Override
    public Boolean testSeata(Integer type, SecurityTest securityTest) {log.info("seata全局事務(wù)ID: {}", RootContext.getXID());if (type!=null&&type==1) {//先遠(yuǎn)程調(diào)用construction服務(wù)保存遠(yuǎn)程服務(wù)數(shù)據(jù)constructionProvider.testSeata(false);//再保存自己服務(wù)數(shù)據(jù)securityTestService.save(securityTest);//模擬調(diào)用方異常throw new RuntimeException("模擬調(diào)用方異常");} else {//先保存自己服務(wù)數(shù)據(jù)securityTestService.save(securityTest);//再遠(yuǎn)程調(diào)用construction服務(wù)保存遠(yuǎn)程服務(wù)數(shù)據(jù),且模擬被調(diào)用方異常constructionProvider.testSeata(true);}return true;
    }
    

    這里測(cè)試兩種情況,調(diào)用方異常事務(wù)回滾,還有被調(diào)用方異常事務(wù)回滾

  • 被調(diào)用方提供的Feign接口

    @Service(value = "IConstructionProvider")
    @FeignClient(value = ConstructionProviderConstant.MATE_CLOUD_CONSTRUCTION, fallback = ConstructionProviderFallback.class)
    public interface IConstructionProvider {/*** 測(cè)試全局事務(wù)* @param error* @return*/@GetMapping(ConstructionProviderConstant.TEST_SEATA)ResponseResult<String> testSeata(@RequestParam("error") Boolean error);}
    

    這里當(dāng)時(shí)遇到了一個(gè)坑

    • 如果不寫@RequestParam(“error”) ,會(huì)識(shí)別成POST請(qǐng)求,然后報(bào)錯(cuò)不支持POST請(qǐng)求

    • 如果寫了@RequestParam,但是沒(méi)設(shè)置value屬性,即寫@RequestParam Boolean error,也會(huì)報(bào)錯(cuò)

      參考:Feign 調(diào)用報(bào) RequestParam.value() was empty on parameter 0-CSDN博客

    實(shí)現(xiàn):

    在這里插入圖片描述

    正常調(diào)用:

    /*** 測(cè)試Seata全局事務(wù)* @param error 是否模擬被調(diào)用方異常* @return*/
    @Override
    @ApiOperation(value = "測(cè)試Seata全局事務(wù)", notes = "測(cè)試Seata全局事務(wù)", 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("模擬被調(diào)用方異常");}return ResponseResult.success("---------------testSeata接口正常------------------");
    }
    

    熔斷降級(jí):

    @Override
    public ResponseResult<String> testSeata(Boolean error) {if (error) {throw new RuntimeException("降級(jí)方法中---模擬被調(diào)用方異常");}return ResponseResult.success("----------------testSeata接口遠(yuǎn)程調(diào)用熔斷-----------------");
    }
    

5.測(cè)試結(jié)果

分別測(cè)試了調(diào)用方異常、被調(diào)用方異常的情況,均能實(shí)現(xiàn)全局事務(wù)回滾(兩邊的數(shù)據(jù)庫(kù)都回滾了),如下圖所示

在這里插入圖片描述

在這里插入圖片描述

下面是seata控制臺(tái)的信息(存于數(shù)據(jù)庫(kù)里)

在這里插入圖片描述

這里我測(cè)試的結(jié)果是 只有調(diào)用方和被調(diào)用方都有事務(wù)回滾 才會(huì)有信息,而且會(huì)定期清除

http://m.aloenet.com.cn/news/40133.html

相關(guān)文章:

  • 網(wǎng)站被模仿如何維權(quán)青島seo整站優(yōu)化哪家專業(yè)
  • ps企業(yè)網(wǎng)站模板免費(fèi)下載百度網(wǎng)盤官方
  • 重慶企業(yè)網(wǎng)站推廣公司合肥網(wǎng)
  • 羅湖中心區(qū)做網(wǎng)站怎么樣建一個(gè)網(wǎng)站
  • 廣州設(shè)計(jì)公司網(wǎng)站廣告營(yíng)銷案例100例
  • 網(wǎng)站開(kāi)發(fā)費(fèi)入什么費(fèi)用中國(guó)十大企業(yè)培訓(xùn)公司
  • 國(guó)外做美食視頻網(wǎng)站有哪些寧波seo外包服務(wù)
  • 柳市網(wǎng)站托管西安網(wǎng)站制作建設(shè)
  • 河池建設(shè)銀行招聘網(wǎng)站百度推廣客服投訴電話
  • 溫州網(wǎng)站設(shè)計(jì)定制市場(chǎng)營(yíng)銷最有效的手段
  • mvc5網(wǎng)站開(kāi)發(fā)之美電子版可靠的網(wǎng)站優(yōu)化
  • dnf怎么做提卡網(wǎng)站谷歌網(wǎng)站收錄提交入口
  • 山東網(wǎng)站排行免費(fèi)的關(guān)鍵詞優(yōu)化軟件
  • 自己做pc網(wǎng)站建設(shè)愛(ài)站網(wǎng)挖掘詞
  • 哪些企業(yè)需要網(wǎng)站建設(shè)的微信客戶管理系統(tǒng)
  • 網(wǎng)站建設(shè)時(shí)如何建立客戶信賴感杭州seo排名
  • 做網(wǎng)站mfdos泰州網(wǎng)站排名seo
  • 網(wǎng)頁(yè)建設(shè)類有哪些軟件seo小白入門教學(xué)
  • 時(shí)時(shí)彩網(wǎng)站怎么建設(shè)關(guān)鍵詞優(yōu)化百家號(hào)
  • WordPress用戶發(fā)表插件廣州seo排名收費(fèi)
  • 做此廣告的網(wǎng)站推廣公司產(chǎn)品
  • 網(wǎng)站建設(shè)做軟件開(kāi)發(fā)嗎大型網(wǎng)站制作
  • 網(wǎng)站開(kāi)發(fā)編程html網(wǎng)頁(yè)設(shè)計(jì)模板
  • 網(wǎng)站建站 免費(fèi)運(yùn)營(yíng)網(wǎng)站
  • 本地wordpress 固定連接優(yōu)化模型有哪些
  • 怎么做淘寶優(yōu)惠券的網(wǎng)站杭州10大軟件開(kāi)發(fā)公司
  • 人民日?qǐng)?bào)客戶端的視頻怎么下載seo全網(wǎng)圖文推廣
  • 企業(yè)網(wǎng)站seo優(yōu)幫云無(wú)限制訪問(wèn)國(guó)外的瀏覽器
  • 做甜點(diǎn)的網(wǎng)站百度手機(jī)seo軟件
  • 建設(shè)培訓(xùn)學(xué)校網(wǎng)站抓取關(guān)鍵詞的軟件