赞
踩
Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。
依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。
Nacos:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
RocketMQ:一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。
Dubbo:Apache Dubbo™ 是一款高性能 Java RPC 框架。
Seata:阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案。
Alibaba Cloud OSS: 阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。
Alibaba Cloud SchedulerX: 阿里中间件团队开发的一款分布式任务调度产品,提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。
Alibaba Cloud SMS: 覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。
如果需要使用已发布的版本,在 dependencyManagement
中添加如下配置。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
然后在 dependencies
中添加自己所需使用的依赖即可使用。
为了演示如何使用,Spring Cloud Alibaba 项目包含了一个子模块spring-cloud-alibaba-examples
。此模块中提供了演示用的 example ,您可以阅读对应的 example 工程下的 readme 文档,根据里面的步骤来体验。
Example 列表:
Alibaba Cloud SchedulerX Example
项目的版本号格式为 x.x.x 的形式,其中 x 的数值类型为数字,从 0 开始取值,且不限于 0~9 这个范围。项目处于孵化器阶段时,第一位版本号固定使用 0,即版本号为 0.x.x 的格式。
由于 Spring Boot 1 和 Spring Boot 2 在 Actuator 模块的接口和注解有很大的变更,且 spring-cloud-commons 从 1.x.x 版本升级到 2.0.0 版本也有较大的变更,因此我们采取跟 SpringBoot 版本号一致的版本:
nacos开启:sh docker-startup.sh -m standalone
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://120.26.11.225:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=hzy1214…
java -jar -Dservice.port=8080 /Downloads/sentinel-dashboard-1.8.1.jar
启动
sh startup.sh -m standalone
1.pom.xml
<dependencies> <!--SpringCloud ailibaba nacos --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- SpringBoot整合Web组件 --> <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> <!--日常通用jar包配置--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
2.yml
server: port: 9001 spring: application: name: cloudalibaba-provider-payment cloud: nacos: discovery: server-addr: 120.26.11.225:8848 management: endpoints: web: exposure: include: '*'
3.启动类
@SpringBootApplication
@EnableDiscoveryClient
public class Cloudalibaba_provider_payment9001 {
public static void main(String[] args) {
SpringApplication.run(Cloudalibaba_provider_payment9001.class,args);
}
}
3.service
@RestController
public class PaymentController {
@Value("${server.port}")
private String serverPort;
@GetMapping("/payment/nacos/{id}")
String getPayment(@PathVariable("id") Integer id) {
return "nacos registry, server port : " + serverPort + ", id : " + id;
}
}
<dependencies> <!--SpringCloud ailibaba nacos --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- 引入自己定义的api通用包,可以使用Payment支付Entity --> <dependency> <groupId>org.example</groupId> <artifactId>cloud-api-commons</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!-- SpringBoot整合Web组件 --> <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> <!--日常通用jar包配置--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
2.yml
server:
port: 83
spring:
application:
name: cloudalibaba-consumer-order-nacos
cloud:
nacos:
discovery:
server-addr: 120.26.11.225:8848
service-url:
nacos-user-service: http://cloudalibaba-provider-payment
3.启动类
@SpringBootApplication
@EnableDiscoveryClient
public class Cloudalibaba_consumer_order_nacos83 {
public static void main(String[] args) {
SpringApplication.run(Cloudalibaba_consumer_order_nacos83.class,args);
}
}
4.config
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
5.controller
@RestController
public class OrderController {
@Resource
private RestTemplate restTemplate;
@Value("${service-url.nacos-user-service}")
private String serviceURL;
@GetMapping("/consumer/paymenr/nacos/{id}")
String nacosPayment(@PathVariable("id") Integer id) {
return restTemplate.getForObject(serviceURL+"/payment/nacos/"+id,String.class);
}
}
pom.xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
@FeignClient(name = "SpringCloudAlibabaPro")
public interface DemoFeign {
@GetMapping("/nacos/{id}")
String t1 (@PathVariable("id") Integer id);
}
@RestController
public class DemoController {
@Autowired
DemoFeign demoFeign;
@GetMapping("/get/{id}")
public String t1 (@PathVariable("id") Integer id) {
return demoFeign.t1(id);
}
}
配置日志信息
//@Configuration 添加注解会将作用所有的服务提供方 //如果是只想针对某一个服务就不需要加 @Bean Logger.Level feign() { /** * NONE:性能最佳适用于生产环境,不记录任何日志(默认值) * BASIC:适用于成产环境的追踪问题,仅记录请求方式,URL,响应码以及执行时间 * HEADERS:记录请求和响应头信息 * FULL:适用于测试环境,记录请求和响应的头信息,body和元数据 */ return Logger.Level.FULL; } logging: level: com.xiaoyu.service: debug
配置超时时间
/** * 全剧配置超时时间针对所有的服务 * 只针对某一个服务的话在yml配置 * @return */ @Bean public Request.Options options () { return new Request.Options(1000,1000); } #针对某一个服务的超时时间设置 #全局和局部都配置的话生效的是局部配置 feign: client: config: SpringCloudAlibabaPro: #默认2s connectTimeout: 3000 # 默认5s readTimeout: 3000
<dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!--nacos-discovery--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--web + actuator--> <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-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
2.yml
application.yml
spring:
profiles:
active: dev
bootstrap.yml
server: port: 3377 spring: application: name: nacos-config cloud: nacos: discovery: server-addr: 120.26.11.225:8848 config: server-addr: 120.26.11.225:8848 file-extension: yaml max-retry: 10 namespace: 123456 group: DEV-GROUP # ${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension} # 结果是:nacos-config-dev.yaml
3.启动类
@SpringBootApplication
@EnableDiscoveryClient
public class Cloudalibaba_config_nacos3377 {
public static void main(String[] args) {
SpringApplication.run(Cloudalibaba_config_nacos3377.class,args);
}
}
4.controller
@RestController
@RefreshScope
public class ConfigController {
@Value("${config.info}")
private String configInfo;
@GetMapping("/config/info")
String getConfigInfo() {
return configInfo;
}
}
查看当前启动多少台nacos
ps -ef|grep nacos|grep -v grep|wc -l
分布式系统的流量防卫兵
服务降级后提示信息为:Blocked by Sentinel (flow limiting)
热点达到阈值后出现页面设置,相当于ex_testD是testD的兜底方法
@GetMapping("/testD")
@SentinelResource(value = "testD",blockHandler = "ex_testD")
public String testD(@RequestParam(value = "p1",required = false) String p1,
@RequestParam(value = "p2",required = false) String p2) {
return "testD";
}
public String ex_testD(String p1, String p2, BlockException blockException) {
return "ex_testD";
}
/*
blockHandler:服务配置规格异常的兜底
fallback负责业务逻辑报错的兜底
exceptionsToIgnore当匹配这个错误的时候不会调用兜底方法
如果方法不在同一个类,则使用以下参数进行配置
blockHandlerClass = ,
fallbackClass =
*/
@SentinelResource(value = "fallback",
fallback = "handlerFallback",
blockHandler = "blockHandler",
exceptionsToIgnore = {RuntimeException.class})
resource:资源名称
limitApp:来源应用
grade:阈值类型
count:单机阈值
strategy:流控模式
controlBehavior:流控效果
clusterMode:是否集群
下载seata
在seata目录下创建config.txt
nsport.type=TCP transport.server=NIO transport.heartbeat=true transport.enableClientBatchSendRequest=true transport.threadFactory.bossThreadPrefix=NettyBoss transport.threadFactory.workerThreadPrefix=NettyServerNIOWorker transport.threadFactory.serverExecutorThreadPrefix=NettyServerBizHandler transport.threadFactory.shareBossWorker=false transport.threadFactory.clientSelectorThreadPrefix=NettyClientSelector transport.threadFactory.clientSelectorThreadSize=1 transport.threadFactory.clientWorkerThreadPrefix=NettyClientWorkerThread transport.threadFactory.bossThreadSize=1 transport.threadFactory.workerThreadSize=default transport.shutdown.wait=3 service.vgroupMapping.my_test_tx_group=default service.default.grouplist=127.0.0.1:8091 service.enableDegrade=false service.disableGlobalTransaction=false client.rm.asyncCommitBufferLimit=10000 client.rm.lock.retryInterval=10 client.rm.lock.retryTimes=30 client.rm.lock.retryPolicyBranchRollbackOnConflict=true client.rm.reportRetryCount=5 client.rm.tableMetaCheckEnable=false client.rm.tableMetaCheckerInterval=60000 client.rm.sqlParserType=druid client.rm.reportSuccessEnable=false client.rm.sagaBranchRegisterEnable=false client.rm.tccActionInterceptorOrder=-2147482648 client.tm.commitRetryCount=5 client.tm.rollbackRetryCount=5 client.tm.defaultGlobalTransactionTimeout=60000 client.tm.degradeCheck=false client.tm.degradeCheckAllowTimes=10 client.tm.degradeCheckPeriod=2000 client.tm.interceptorOrder=-2147482648 store.lock.mode=file store.session.mode=file store.publicKey= store.file.dir=file_store/data store.file.maxBranchSessionSize=16384 store.file.maxGlobalSessionSize=512 store.file.fileWriteBufferCacheSize=16384 store.file.flushDiskMode=async store.file.sessionReloadReadSize=100 store.db.datasource=druid store.db.dbType=mysql store.db.driverClassName=com.mysql.jdbc.Driver store.db.url=jdbc:mysql://localhost:3306/seata?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true store.db.user=root store.db.password=Hzyy1214 store.db.minConn=5 store.db.maxConn=30 store.db.globalTable=global_table store.db.branchTable=branch_table store.db.queryLimit=100 store.db.lockTable=lock_table store.db.maxWait=5000 store.redis.mode=single store.redis.single.host=127.0.0.1 store.redis.single.port=6379 store.redis.sentinel.masterName= store.redis.sentinel.sentinelHosts= store.redis.maxConn=10 store.redis.minConn=1 store.redis.maxTotal=100 store.redis.database=0 store.redis.password= store.redis.queryLimit=100 server.recovery.committingRetryPeriod=1000 server.recovery.asynCommittingRetryPeriod=1000 server.recovery.rollbackingRetryPeriod=1000 server.recovery.timeoutRetryPeriod=1000 server.maxCommitRetryTimeout=-1 server.maxRollbackRetryTimeout=-1 server.rollbackRetryTimeoutUnlockEnable=false server.distributedLockExpireTime=10000 client.undo.dataValidation=true client.undo.logSerialization=jackson client.undo.onlyCareUpdateColumns=true server.undo.logSaveDays=7 server.undo.logDeletePeriod=86400000 client.undo.logTable=undo_log client.undo.compress.enable=true client.undo.compress.type=zip client.undo.compress.threshold=64k log.exceptionRate=100 transport.serialization=seata transport.compressor=none metrics.enabled=false metrics.registryType=compact metrics.exporterList=prometheus metrics.exporterPrometheusPort=9898
上述配置解读:
service.vgroupMapping.my_test_tx_group=default 配置信息到nacos的分组默认default
service.default.grouplist=127.0.0.1:8091 seata的ip端口
配置数据库 store.db.datasource=druid store.db.dbType=mysql store.db.driverClassName=com.mysql.jdbc.Driver store.db.url=jdbc:mysql://localhost:3306/seata?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true store.db.user=root store.db.password=Hzyy1214
- 1
- 2
- 3
- 4
- 5
- 6
- 7
数据库的表默认名称即可,如果数据库表修改这里也要修改 store.db.globalTable=global_table store.db.branchTable=branch_table store.db.queryLimit=100 store.db.lockTable=lock_table
- 1
- 2
- 3
- 4
- 5
在conf目录创建nacos-config.sh脚本用于提交config.txt的配置信息到nacos
opyright 1999-2019 Seata.io Group. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at、 # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. while getopts ":h:p:g:t:u:w:" opt do case $opt in h) host=$OPTARG ;; p) port=$OPTARG ;; g) group=$OPTARG ;; t) tenant=$OPTARG ;; u) username=$OPTARG ;; w) password=$OPTARG ;; ?) echo " USAGE OPTION: $0 [-h host] [-p port] [-g group] [-t tenant] [-u username] [-w password] " exit 1 ;; esac done urlencode() { for ((i=0; i < ${#1}; i++)) do char="${1:$i:1}" case $char in [a-zA-Z0-9.~_-]) printf $char ;; *) printf '%%%02X' "'$char" ;; esac done } if [[ -z ${host} ]]; then host=localhost fi if [[ -z ${port} ]]; then port=8848 fi if [[ -z ${group} ]]; then group="SEATA_GROUP" fi if [[ -z ${tenant} ]]; then tenant="" fi if [[ -z ${username} ]]; then username="" fi if [[ -z ${password} ]]; then password="" fi nacosAddr=$host:$port contentType="content-type:application/json;charset=UTF-8" echo "set nacosAddr=$nacosAddr" echo "set group=$group" failCount=0 tempLog=$(mktemp -u) function addConfig() { curl -X POST -H "${contentType}" "http://$nacosAddr/nacos/v1/cs/configs?dataId=$(urlencode $1)&group=$group&content=$(urlencode $2)&tenant=$tenant&username=$username&password=$password" >"${tempLog}" 2>/dev/null if [[ -z $(cat "${tempLog}") ]]; then echo " Please check the cluster status. " exit 1 fi if [[ $(cat "${tempLog}") =~ "true" ]]; then echo "Set $1=$2 successfully " else echo "Set $1=$2 failure " (( failCount++ )) fi } count=0 for line in $(cat $(dirname "$PWD")/config.txt | sed s/[[:space:]]//g); do (( count++ )) key=${line%%=*} value=${line#*=} addConfig "${key}" "${value}" done echo "=========================================================================" echo " Complete initialization parameters, total-count:$count , failure-count:$failCount " echo "=========================================================================" if [[ ${failCount} -eq 0 ]]; then echo " Init nacos config finished, please start seata-server. " else echo " init nacos config fail. " fi
修改配置文件file.config
在 file.config中 store.db.driverClassName 默认是 com.mysql.jdbc.Driver。 mysql8.0是 com.mysql.cj.jdbc.Drive
执行命令提交配置信息
sh nacos-config.sh ip
- 1
启动seata
sh seata-server.sh -h nacos的ip地址
- 1
1+3
1:transactionID XID 全局唯一的事物ID
3:3组件概念:
分布式事务模式 | 介绍 | 技术栈 |
---|---|---|
AT 模式 | 无侵入的分布式事务解决方案,适用于不希望对业务进行改造的场景,几乎0学习成本(sql都由框架托管统一执行,会存在脏写问题) | seata、shardingsphere |
TCC 模式 | 高性能分布式事务解决方案,适用于核心系统等对性能有很高要求的场景(第一阶段会产生行锁,事务执行太久会锁行很久) | seata、service-comb |
Saga 模式 | 长事务解决方案,适用于业务流程长且需要保证事务最终一致性的业务系统(第一阶段就操作DB,会存在脏读问题) | seata、shardingsphere、service-comb |
XA模式 | 分布式强一致性的解决方案,但性能低而使用较少。 | seata、shardingsphere |
启动命令:sh seata-server.sh -p 9999 -h 120.26.11.225
后台启动:nohup sh seata-server.sh -p 9999 -h 120.26.11.225 -m file >nohup.out 2>1 &
需要修改conf文件夹的file.conf改为db和配置数据库连接信息,具体建数据库信息如下,registry.conf修改为nacos配置nacos信息
创建数据库和表,如图
sql语句:
seata数据库:
-- -------------------------------- The script used when storeMode is 'db' -------------------------------- -- the table to store GlobalSession data CREATE DATABASE seate; USE seate; CREATE TABLE IF NOT EXISTS `global_table` ( `xid` VARCHAR(128) NOT NULL, `transaction_id` BIGINT, `status` TINYINT NOT NULL, `application_id` VARCHAR(32), `transaction_service_group` VARCHAR(32), `transaction_name` VARCHAR(128), `timeout` INT, `begin_time` BIGINT, `application_data` VARCHAR(2000), `gmt_create` DATETIME, `gmt_modified` DATETIME, PRIMARY KEY (`xid`), KEY `idx_gmt_modified_status` (`gmt_modified`, `status`), KEY `idx_transaction_id` (`transaction_id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8; -- the table to store BranchSession data CREATE TABLE IF NOT EXISTS `branch_table` ( `branch_id` BIGINT NOT NULL, `xid` VARCHAR(128) NOT NULL, `transaction_id` BIGINT, `resource_group_id` VARCHAR(32), `resource_id` VARCHAR(256), `branch_type` VARCHAR(8), `status` TINYINT, `client_id` VARCHAR(64), `application_data` VARCHAR(2000), `gmt_create` DATETIME(6), `gmt_modified` DATETIME(6), PRIMARY KEY (`branch_id`), KEY `idx_xid` (`xid`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8; -- the table to store lock data CREATE TABLE IF NOT EXISTS `lock_table` ( `row_key` VARCHAR(128) NOT NULL, `xid` VARCHAR(128), `transaction_id` BIGINT, `branch_id` BIGINT NOT NULL, `resource_id` VARCHAR(256), `table_name` VARCHAR(32), `pk` VARCHAR(36), `gmt_create` DATETIME, `gmt_modified` DATETIME, PRIMARY KEY (`row_key`), KEY `idx_branch_id` (`branch_id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8;
seata_account/order/storage数据库:
CREATE DATABASE seata_order; USE seata_order; CREATE TABLE t_order( id BIGINT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY , user_id BIGINT(11) DEFAULT NULL COMMENT '用户id', product_id BIGINT(11) DEFAULT NULL COMMENT '产品id', count INT(11) DEFAULT NULL COMMENT '数量', money DECIMAL(11,0) DEFAULT NULL COMMENT '金额', status INT(1) DEFAULT NULL COMMENT '订单状态:0创建中,1已完结' )ENGINE=InnoDB AUTO_INCREMENT=7 CHARSET=utf8; CREATE DATABASE seata_storage; USE seata_storage; CREATE TABLE t_storage( id BIGINT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY , product_id BIGINT(11) DEFAULT NULL COMMENT '产品id', total INT(11) DEFAULT NULL COMMENT '总库存', used INT(11) DEFAULT NULL COMMENT '已用库存', residue INT(11) DEFAULT NULL COMMENT '剩余库存' )ENGINE=InnoDB AUTO_INCREMENT=7 CHARSET=utf8; INSERT INTO t_storage(id, product_id, total, used, residue) VALUES(1,1,100,0,100); CREATE DATABASE seata_account; USE seata_account; CREATE TABLE t_account( id BIGINT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY , user_id BIGINT(11) DEFAULT NULL COMMENT '用户id', total DECIMAL(10,0) DEFAULT NULL COMMENT '总额度', used DECIMAL(10,0) DEFAULT NULL COMMENT '已用额度', residue DECIMAL(10,0) DEFAULT 0 COMMENT '剩余可用额度' )ENGINE=InnoDB AUTO_INCREMENT=7 CHARSET=utf8; INSERT INTO t_account(id, user_id, total, used, residue) VALUES(1,1,1000,0,1000);
<dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-seata</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--feign--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!--web-actuator--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--mysql-druid--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.23</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.0.5</version> </dependency> </dependencies>
seata: enabled: true enable-auto-data-source-proxy: true tx-service-group: my_test_tx_group registry: type: nacos nacos: application: seata-server server-addr: 127.0.0.1:8848 username: nacos password: nacos config: type: nacos nacos: server-addr: 127.0.0.1:8848 group: SEATA_GROUP username: nacos password: nacos namespace: 0af6e97b-a684-4647-b696-7c6d42aecce7 service: vgroupMapping: my_test_tx_group: default disable-global-transaction: false client: rm: report-success-enable: false spring: application: name: Seata datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/seata_order?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true username: root password: Hzyy1214 server: port: 8999
package com.xiaoyu.config; import com.zaxxer.hikari.HikariDataSource; import io.seata.rm.datasource.DataSourceProxy; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import javax.sql.DataSource; @Configuration public class DataSourceProxyConfig { /** * 需要将 DataSourceProxy 设置为主数据源,否则事务无法回滚 */ @Primary @Bean("dataSource") public DataSource dataSource(@Value("${spring.datasource.url}")String url, @Value("${spring.datasource.driver-class-name}")String driverClassName, @Value("${spring.datasource.username}")String username, @Value("${spring.datasource.password}")String password) { HikariDataSource hikariDataSource = new HikariDataSource(); hikariDataSource.setJdbcUrl(url); hikariDataSource.setDriverClassName(driverClassName); hikariDataSource.setUsername(username); hikariDataSource.setPassword(password); return new DataSourceProxy(hikariDataSource); } }
@Service public class OrderService { //出现异常自动回滚无异常自动提交 @GlobalTransactional(name = "my_test_tx_group", rollbackFor = Exception.class) public void t1() { //业务逻辑 } //捕捉异常手动回滚 public void t2() { GlobalTransaction globalTransaction = GlobalTransactionContext.getCurrentOrCreate(); try { //开始事物 globalTransaction.begin(3000, "my_test_tx_group"); //业务逻辑 //没有异常提交事务 globalTransaction.commit(); } catch (Exception e) { try { //出现异常回滚事务 globalTransaction.rollback(); } catch (TransactionException ex) { ex.printStackTrace(); } } } }
使用openfeign调用其他服务时,参数>=两个会报错,解决办法:
使用@RequestParam(“id”)
@FeignClient(value = "Seata-Storage") public interface StorageService { @GetMapping("/update/storage") String updateStorage (@RequestParam("id") Integer id,@RequestParam("account") Integer account); }
- 1
- 2
- 3
- 4
- 5
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。