一、seata简介
seata官网:
https://github.com/seata/seata
二、seata整合dubbo
2.1 seata整合nacos
file.conf 修改为db
registry.conf 修改为 nacos
sh ${SEATAPATH}/script/config-center/nacos/nacos-config.sh -h localhost -p 8848 -g SEATA_GROUP -t 5a3c7d6c-f497-4d68-a71a-2e5e3340b3ca
seata-server.bat -p 8081
2.2 下载数据库脚本
https://github.com/seata/seata/tree/1.2.0/script/client/at/db
-- for AT mode you must to init this sql for you business database. the seata server not need it.
CREATE TABLE IF NOT EXISTS `undo_log`
(
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT 'increment id',
`branch_id` BIGINT(20) NOT NULL COMMENT 'branch transaction id',
`xid` VARCHAR(100) NOT NULL COMMENT 'global transaction id',
`context` VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',
`rollback_info` LONGBLOB NOT NULL COMMENT 'rollback info',
`log_status` INT(11) NOT NULL COMMENT '0:normal status,1:defense status',
`log_created` DATETIME NOT NULL COMMENT 'create datetime',
`log_modified` DATETIME NOT NULL COMMENT 'modify datetime',
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
AUTO_INCREMENT = 1
DEFAULT CHARSET = utf8 COMMENT ='AT transaction mode undo table';
2.3 demo
主要maven依赖
<!-- 基准测试-->
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.21</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.21</version>
<scope>test</scope>
</dependency>
<!-- Spring Cloud Begin -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>top.xxx</groupId>
<artifactId>dubbo-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
配置
#consumer配置:
# 端口
server.port=8080
spring.profiles.active=pro
spring.application.name=dubbo-consumer
# 日志
logging.level.top.xxx=DEBUG
logging.level.com.alibaba.nacos.client.naming=ERROR
# jackson
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
# 数据源
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:${MYSQL_PORT:3306}/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull
spring.datasource.username=admin
spring.datasource.password=12345678
# Hikari will use the above plus the following to setup connection pooling
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.pool-name=dubbo-consumer
spring.datasource.hikari.minimum-idle=1
spring.datasource.hikari.maximum-pool-size=15
spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.connection-test-query=SELECT 1
# mybatis
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
mybatis-plus.mapper-locations=classpath:/mappers/*.xml
# redis
spring.redis.host=${redis.host:127.0.0.1}
spring.redis.port=${redis.port:6379}
spring.redis.lettuce.pool.max-active=${redis.pool.maxActive:300}
spring.redis.lettuce.pool.max-idle=${redis.pool.maxIdle:100}
spring.redis.lettuce.pool.max-wait=${redis.pool.maxWait:1000}
spring.redis.lettuce.pool.min-idle=${redis.minIdle:0}
# spring boot actuator端点启用和暴露
## * 可以用来表示所有的端点,例如,通过HTTP公开所有的端点
## * 在YAML中有特殊的含义,所以如果想使用include或者exclude包含所有的端点时要加上双引号
management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=env,beans
management.endpoints.promethus.enable=true
management.endpoint.health.show-details=always
spring:
redisson:
address: xxx:6379
timeout: 3000
database: 0
pool:
max-active: 20
max-idle: 10
max-wait: 3000
min-idle: 4
dubbo:
application:
name: dubbo-consumer
consumer:
check: false
filter: rpcFilter
protocol:
name: dubbo
port: 20881
accesslog: dubbo-acccess.log
registry:
address: zookeeper://localhost:2181
check: true
group: dubbo-lai-1
simplified: true
metadata-report:
address: zookeeper://localhost:2181
retry-times: 30
cycle-report: false
group: dubbo-lai-1
scan:
base-packages:
monitor:
protocol: registry
seata:
tx-service-group: blade-seata-order-group
service:
grouplist:
default: 127.0.0.1:8091
vgroup-mapping:
blade-seata-order-group: default
disable-global-transaction: false
client:
rm:
report-success-enable: false
#producer
# 端口
server.port=8086
spring.profiles.active=pro
spring.application.name=dubbo-producer
# 日志
logging.level=DEBUG
logging.level.com.alibaba.nacos.client.naming=ERROR
# jackson
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
# 数据源
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:${MYSQL_PORT:3306}/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull
spring.datasource.username=admin
spring.datasource.password=12345678
# Hikari will use the above plus the following to setup connection pooling
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.pool-name=dubbo-producer
spring.datasource.hikari.minimum-idle=1
spring.datasource.hikari.maximum-pool-size=15
spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.connection-test-query=SELECT 1
# mybatis
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
mybatis-plus.mapper-locations=classpath:/mappers/*.xml
# redis
spring.redis.host=${redis.host:127.0.0.1}
spring.redis.port=${redis.port:6379}
spring.redis.lettuce.pool.max-active=${redis.pool.maxActive:300}
spring.redis.lettuce.pool.max-idle=${redis.pool.maxIdle:100}
spring.redis.lettuce.pool.max-wait=${redis.pool.maxWait:1000}
spring.redis.lettuce.pool.min-idle=${redis.minIdle:0}
# spring boot actuator端点启用和暴露
## * 可以用来表示所有的端点,例如,通过HTTP公开所有的端点
## * 在YAML中有特殊的含义,所以如果想使用include或者exclude包含所有的端点时要加上双引号
management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=env,beans
management.endpoints.promethus.enable=true
management.endpoint.health.show-details=always
spring:
redisson:
address:
timeout: 3000
database: 0
pool:
max-active: 20
max-idle: 10
max-wait: 3000
min-idle: 4
dubbo:
provider:
filter: rpcFilter
application:
name: dubbo-producer
protocol:
name: dubbo
port: 20880
accesslog: dubbo-acccess.log
registry:
address: zookeeper://localhost:2181
check: true
group: dubbo-lai-1
simplified: true
metadata-report:
address: zookeeper://localhost:2181
retry-times: 30
cycle-report: false
group: dubbo-lai-1
scan:
base-packages:
monitor:
protocol: registry
seata:
tx-service-group: blade-seata-storage-group
service:
grouplist:
default: 127.0.0.1:8091
vgroup-mapping:
blade-seata-storage-group: default
disable-global-transaction: false
client:
rm:
report-success-enable: false
controller配置
/**
使用@GlobalTransactional开启事务
在业务的发起方的方法上使用@GlobalTransactional开启全局事务,Seata 会将事务的 xid 通过拦截器添加到调用其他服务的请求中,实现分布式事务
*/
@RestController
public class BaseController {
@Autowired
private BaseService baseService;
@Reference(loadbalance = "roundrobin", timeout = 30000,mock = "")
private RpcService rpcService;
@RequestMapping("saveRpc")
@GlobalTransactional
public BaseResponse test(@RequestBody RpcDto rpcDto){
return rpcService.save (rpcDto);
}
}
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Service
public class RpcServiceImpl implements RpcService {
@Autowired
private RpcMapper rpcMapper;
@GlobalTransactional
public BaseResponse saveRpc(RpcDto rpcDto) {
save(rpcDto);
int a = 0;
a = 1/0;
return BaseResponse.success ();
}
@Override
public BaseResponse save(RpcDto rpcDto) {
rpcDto.setCreateTime (new Date ());
rpcDto.setUpdateTime (new Date ());
Rpc rpcDb = new Rpc ();
BeanUtils.copyProperties (rpcDto, rpcDb);
rpcMapper.insert (rpcDb);
return BaseResponse.success ();
}
}