Seata 与 SpringBoot 集成 实现2PC模式的分布式事务
Last updated
Was this helpful?
Last updated
Was this helpful?
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>source-seata-code</artifactId>
<groupId>com.javayh.advanced</groupId>
<version>1.0.0.RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<description>springboot mybatis seata 集成demo</description>
<artifactId>boot-mybatis-seata-code</artifactId>
<packaging>pom</packaging>
<modules>
<module>seata-prod-code</module>
<module>seata-coms-code</module>
</modules>
<properties>
<spring-cloud-dependencies.version>Hoxton.SR8</spring-cloud-dependencies.version>
<spring-cloud-alibaba-dependencies.version>2.2.5.RELEASE</spring-cloud-alibaba-dependencies.version>
</properties>
<dependencies>
<!--<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.4.1</version>
</dependency>-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<!-- Spring Cloud Nacos Service Discovery -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Spring Cloud Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- Spring Cloud Seata -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud-dependencies.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--alibaba cloud-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba-dependencies.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
创建两个服务
seata-prod-code
seata-coms-code
创建两个数据库
导入init.sql
undo_log两个数据库需要都导入
其他的两张表一个数据库一个
服务的配置
这个服务每个服务都需要添加
server:
port: 9012
spring:
application:
name: boot-seata-app-coms
mvc:
throw-exception-if-no-handler-found: true
main:
allow-bean-definition-overriding: true
cloud:
# nacos 配置
nacos:
config:
enabled: true
namespace: 97447291-3fc6-44bd-8572-27f359df652e
server-addr: 127.0.0.1:8848
discovery:
namespace: 97447291-3fc6-44bd-8572-27f359df652e
server-addr: 127.0.0.1:8848
#设置注册的ip地址
ip: 127.0.0.1
#取值范围 1 到 100,数值越大,权重越大
weight: 5
datasource:
# type: io.seata.rm.datasource.DataSourceProxy
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/dalao?serverTimezone=CTT&characterEncoding=utf8&autoReconnect=true&useUnicode=true&useSSL=true
username: root
password: root
# hikari:
# minimum-idle: 10
# maximum-pool-size: 30
# auto-commit: true
# idle-timeout: 30000
# pool-name: DemoHikari
# max-lifetime: 60000
# connection-timeout: 60000
# validation-timeout: 5000
# read-only: false
# login-timeout: 5
## mybatis 常用配置
mybatis:
### xml存放路径
mapper-locations: classpath*:mapper/*/*Mapper.xml
configuration:
cache-enabled: true
lazy-loading-enabled: false
aggressive-lazy-loading: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
seata:
enabled: true
application-id: ${spring.application.name}
tx-service-group: my_test_tx_group
#enable-auto-data-source-proxy: true
#use-jdk-proxy: false
client:
rm:
async-commit-buffer-limit: 1000
report-retry-count: 5
table-meta-check-enable: false
report-success-enable: false
lock:
retry-interval: 10
retry-times: 30
retry-policy-branch-rollback-on-conflict: true
tm:
commit-retry-count: 5
rollback-retry-count: 5
undo:
data-validation: true
log-serialization: jackson
log-table: undo_log
log:
exceptionRate: 100
service:
vgroup-mapping:
my_test_tx_group: default
grouplist:
default: 127.0.0.1:8091
#enable-degrade: false
#disable-global-transaction: false
transport:
shutdown:
wait: 3
thread-factory:
boss-thread-prefix: NettyBoss
worker-thread-prefix: NettyServerNIOWorker
server-executor-thread-prefix: NettyServerBizHandler
share-boss-worker: false
client-selector-thread-prefix: NettyClientSelector
client-selector-thread-size: 1
client-worker-thread-prefix: NettyClientWorkerThread
worker-thread-size: default
boss-thread-size: 1
type: TCP
server: NIO
heartbeat: true
serialization: seata
compressor: none
enable-client-batch-send-request: true
# config:
# type: file
# consul:
# server-addr: 127.0.0.1:8500
# apollo:
# apollo-meta: http://192.168.1.204:8801
# app-id: seata-server
# namespace: application
# etcd3:
# server-addr: http://localhost:2379
# nacos:
# namespace:
# serverAddr: localhost
# group: SEATA_GROUP
# zk:
# server-addr: 127.0.0.1:2181
# session-timeout: 6000
# connect-timeout: 2000
# username: ""
# password: ""
registry:
type: file
consul:
cluster: default
server-addr: 127.0.0.1:8500
# etcd3:
# cluster: default
# serverAddr: http://localhost:2379
# eureka:
# application: default
# weight: 1
# service-url: http://localhost:8761/eureka
# nacos:
# cluster: default
# server-addr: localhost
# namespace:
# redis:
# server-addr: localhost:6379
# db: 0
# password:
# cluster: default
# timeout: 0
# sofa:
# server-addr: 127.0.0.1:9603
# application: default
# region: DEFAULT_ZONE
# datacenter: DefaultDataCenter
# cluster: default
# group: SEATA_GROUP
# addressWaitTime: 3000
# zk:
# cluster: default
# server-addr: 127.0.0.1:2181
# session-timeout: 6000
# connect-timeout: 2000
# username: ""
# password: ""
业务代码编写
prod
@Slf4j
@Service
public class GoodsService {
@Autowired
private ComsClient comsClient;
@Resource
private GoodsDao goodsDao;
/**
*
* @param account
*/
@Transactional(rollbackFor = Exception.class)
@GlobalTransactional(rollbackFor = Exception.class)
public void updateAccount(int account){
log.info("开启全局事务 id 为 {}", RootContext.getXID());
goodsDao.updateAccount(account);
//远程调用
String goods = comsClient.goods(account);
if("fallback".equalsIgnoreCase(goods)){
throw new RuntimeException("服务调用异常");
}
if (10 == account){
throw new RuntimeException("人为制造异常");
}
}
}
coms
@Slf4j
@Service
public class GoodsService {
@Resource
private GoodsDao goodsDao;
/**
*
* @param account
*/
//@GlobalTransactional(rollbackFor = Exception.class)
@Transactional(rollbackFor = Exception.class)
public String updateAccount(int account){
log.info("开启全局事务 id 为 {}", RootContext.getXID());
goodsDao.updateAccount(account);
if(account == 5){
//throw new RuntimeException("测试失败回滚");
return "1";
}
return "0";
}
}
启动服务进行测试
下载 Nacos 本文使用的是1.4.1
下载 Seata 本文使用的是1.4.1
创建两个数据库并将init.sql导入
undo_log创建到prod 项目所连接的数据库
启动 prod 、coms
项目
访问