在项目中集成 Seata(AT模式)
首先,更新 到 版本: 引入 Seata 相关的依赖定义: 修改 加入 Seata 相关的配置: 只需要用普通的 标签来声明: 业务端(通常是微服务)的数据库中需要创建一个 表: 需要用 Seata 提供的 标签声明一次分布式事务的开始:
一、修改项目配置引入 Seata
首先,更新 codo-java-bom 到 1.2.4 版本:
<parent>
<groupId>com.codo.tech</groupId>
<artifactId>codo-java-bom</artifactId>
<version>1.2.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
引入 Seata 相关的依赖定义:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<!-- (6)替换 spring-cloud-starter-alibaba-seata -->
<dependency>
<groupId>com.codo.tech</groupId>
<artifactId>spring-cloud-starter-alibaba-seata-codo</artifactId>
<version>2.2.7</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</dependency>
修改 application.yml 加入 Seata 相关的配置:
spring:
application:
# (1)应用名称
name: account-service
seata:
enabled: true
# (1)应用名称
application-id: account-service
# (2)事务组
tx-service-group: creeks_tx_group
enable-auto-data-source-proxy: true
service:
vgroup-mapping:
# (3)事务组对应服务器组 "default"
creeks_tx_group: default
grouplist:
# (4)虚拟服务器组 "default" 的服务器列表
default: ${SEATA_SERVICE:127.0.0.1:8091}
client:
rm:
lock:
# 将此选项设置为 false,当发生锁冲突时,会进行若干次的重试
retry-policy-branch-rollback-on-conflict: false
# 避免跟 sleuth 的自动配置冲突
feign:
enabled: false
相关配置说明
| 编号 | 说明 |
|---|---|
| (1) | 应用名称,spring.application 和 seata.application-id 两个配置必须一致 |
| (2) | 事务组:目前统一使用 creeks_tx_group |
| (3)(4) | 定义使用的 seata-server 地址 |
| (4) | 其中 127.0.0.1:8091 是个人开发环境的地址;部署在 Kubernetes 集群中的地址是 seata:8091(配置源文件) |
| (5) | 需要移除 hikari 的配置,因为 Seata 会使用 druid 作为数据库连接池 |
| (6) | spring-cloud-starter-alibaba-seata-codo 是对官方的 spring-cloud-starter-alibaba-seata 的改造,主要解决了跟 sleuth 的自动配置冲突 |
二、修改 Java 代码支持分布式事务
2.1 有数据库操作的地方(通常是微服务)
只需要用普通的 @Transactional 标签来声明:
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class AccountService {
@Transactional(rollbackFor = Exception.class)
public void debit(String userId, BigDecimal num) {
// 业务逻辑
}
}
业务端(通常是微服务)的数据库中需要创建一个 undo_log 表:
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,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
2.2 协调入口(通常在 creeks-on-api)
需要用 Seata 提供的 @GlobalTransactional 标签声明一次分布式事务的开始:
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.stereotype.Service;
@Service
public class BusinessService {
@GlobalTransactional
public void purchase(String userId, String commodityCode, int orderCount) {
// 业务编排逻辑
}
}
三、如何启动本地测试用的 seata-server
最新的 creekson-deploy-dev 已经集成了 seata-server,更新代码后,进入 deploy-local 目录,执行下面的命令启动服务:
docker-compose up -d seata1
启动的 Seata 服务会监听 8091 端口。