微服务架构下的分布式事务困境
单体应用拆分为微服务后,本地事务无法覆盖跨服务的数据一致性需求。后端开发中,一个订单创建流程可能涉及库存扣减、账户余额变更、积分增加三个独立服务,任何一步失败都需要整体回滚。消息中间件最终一致性方案在业务补偿逻辑上成本极高,Seata的AT模式通过拦截SQL自动生成回滚日志,对业务代码零侵入,是当前微服务架构中分布式事务的主流解法。
Seata Server部署与配置
Seata 1.8+版本推荐使用注册中心模式,Nacos作为注册与配置中心:
# seata-server application.yml
server:
port: 7091
seata:
config:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
namespace: seata
group: SEATA_GROUP
registry:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
namespace: seata
group: SEATA_GROUP
application: seata-server
store:
mode: db
db:
datasource: druid
db-type: mysql
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/seata?useSSL=false
user: seata
password: <password>
Seata数据库需创建三张核心表:global_table、branch_table、lock_table,建表脚本在Seata官方仓库的script目录中。
Spring Boot服务端集成
每个参与分布式事务的微服务都需要集成Seata Client。以订单服务为例:
<!-- pom.xml依赖 -->
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<version>2022.0.0.0</version>
<exclusions>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
业务数据库中创建undo_log表,Seata AT模式依赖此表记录数据修改前后镜像:
CREATE TABLE `undo_log` (
`id` bigint NOT NULL AUTO_INCREMENT,
`branch_id` bigint NOT NULL,
`xid` varchar(128) NOT NULL,
`context` varchar(128) NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int 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` (`xid`,`branch_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
分布式事务注解使用
在事务发起方(Transaction Manager)标注@GlobalTransactional:
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private StockClient stockClient;
@Autowired
private AccountClient accountClient;
@GlobalTransactional(name = "create-order", rollbackFor = Exception.class)
public OrderResult createOrder(OrderRequest request) {
// 1. 创建订单(本地事务)
Order order = new Order();
order.setUserId(request.getUserId());
order.setProductId(request.getProductId());
order.setQuantity(request.getQuantity());
order.setAmount(request.getAmount());
order.setStatus("INIT");
orderMapper.insert(order);
// 2. 扣减库存(远程调用)
stockClient.deduct(request.getProductId(), request.getQuantity());
// 3. 扣减账户余额(远程调用)
accountClient.debit(request.getUserId(), request.getAmount());
// 4. 更新订单状态
order.setStatus("PAID");
orderMapper.updateById(order);
return OrderResult.success(order.getId());
}
}
高并发场景下的性能调优
Seata AT模式在数据竞争激烈的场景中存在锁等待问题。高并发设计的核心是减少全局锁持有时间:
# Seata客户端配置优化
seata:
client:
rm:
async-commit-buffer-limit: 20000
report-retry-count: 5
table-meta-check-enable: true
report-success-enable: false
saga-branch-register-enable: false
sql-parser-type: druid
tm:
# 全局事务超时(毫秒),高并发场景适当缩短
default-global-transaction-timeout: 30000
# 降级开关
degrade-check: true
degrade-check-period: 2000
undo:
data-validation: true
log-serialization: jackson
服务治理与降级策略
Seata Server宕机时,默认行为是阻塞所有分布式事务请求。生产环境中需要配置降级策略:
@Configuration
public class SeataDegradationConfig {
@Bean
public FailureHandler failureHandler() {
return (xid, resourceId, applicationData, e) -> {
log.warn("Seata global transaction failed, xid={}, fallback to local", xid);
MetricsCollector.recordSeataFallback(xid, resourceId, e);
};
}
}
API接口规范中需在响应头中携带全局事务ID,方便链路追踪:
@Aspect
@Component
public class XidPropagationAspect {
@Autowired
private HttpServletResponse response;
@Around("@annotation(globalTransactional)")
public Object propagateXid(ProceedingJoinPoint joinPoint,
GlobalTransactional globalTransactional) throws Throwable {
String xid = RootContext.getXID();
if (xid != null) {
response.setHeader("X-Seata-Xid", xid);
}
return joinPoint.proceed();
}
}
分布式事务监控与告警
Seata Server暴露的Prometheus指标需重点监控:
# Seata关键监控指标
seata_transaction_total{status="committed"} # 已提交事务数
seata_transaction_total{status="rollbacked"} # 已回滚事务数
seata_transaction_total{status="timeout"} # 超时事务数
seata_session_active_count # 活跃全局会话数
# Prometheus告警规则
- alert: SeataHighRollbackRate
expr: |
rate(seata_transaction_total{status="rollbacked"}[5m])
/ rate(seata_transaction_total[5m]) > 0.3
for: 3m
labels:
severity: warning
annotations:
summary: "Seata事务回滚率超过30%"
分布式事务是微服务架构中不可避免的复杂度。Seata AT模式通过SQL拦截自动管理回滚日志,降低了业务代码侵入,但在高并发场景下全局锁的争用是性能瓶颈所在。缩短事务范围、优化锁持有时间、配置降级策略、监控回滚率四项措施组合实施,才能在一致性和性能之间取得平衡。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/springboot-wei-fu-wu-jia-gou-zhong-fen-bu-shi-shi-wu-de/