Spring分布式事务实现

简介: Spring 分布式事务实现

本文已收录在Github关注我,紧跟本系列专栏文章,咱们下篇再续!

  • 🚀 魔都架构师 | 全网30W技术追随者
  • 🔧 大厂分布式系统/数据中台实战专家
  • 🏆 主导交易系统百万级流量调优 & 车联网平台架构
  • 🧠 AIGC应用开发先行者 | 区块链落地实践者
  • 🌍 以技术驱动创新,我们的征途是改变世界!
  • 👉 实战干货:编程严选网

0 前言

基于MQ,JTA实现多服务的分布式事务:

Order service监听新订单队列中的消息,获取后新增订单:

  • 成功,则往新订单缴费队列中写消息,中间新增订单的过程用JTA事务管理,当新增失败则事务回滚,不会往新订单缴费队列中写消息

User service扣费成功后,往新订单转移票队列写消息,这时Ticket service 正在处理中或者处理中发生了失败,这中间的过程中用户查看自己的余额已经扣费成功,但票的信息却没有,此时可以使用事务失败回滚的方式依次回退,这种叫弱一致性;又或者可以把处理失败的内容发送至一个错误队列中,由人工处理等方式解决,即最终一致性。

使用Spring JTA

可用:

  • 如JBoss之类应用服务器提供的JTA事务管理器
  • Atomikos、Bitronix等库提供的JTA事务管理器

禁用JTA

为啥禁用JTA?因为JTA采用两阶段提交方式:

  • 预备阶段
  • 正式提交

当第一次提交出现错误,则整个事务出现回滚,一个事务的时间可能会较长,因为它要跨越多个数据库多个数据资源的的操作,所以在性能上可能会造成吞吐量低。

不用JTA,咋实现事务?依次提交两事务:

  1. start MQ transaction
  2. receive message 读取消息:出错时,message transaction直接回滚
  3. start DB transaction
  4. update DB:出错时,由于此时database transaction、message transaction都尚未提交,这时虽然已经读取了消息,但只要 MQ 支持事务功能,消息就会被回滚,重新放回MQ,重试重新触发该方法
  5. commit DB transaction:出错时,和上一点原因相同
  6. commit MQ transaction:出错时,database transaction已被提交了,所以无法回滚。MQ 事务尚未提交,所以可直接回滚。这也就是不使用 JTA 时遇到的最大难题。所以 spring 也提供了很多机制保障

消息放回至MQ队列,重试重新触发该方法。 当这一步出现错误时,上面的因为已经commit,所以不会rollback

1 多数据源的事务同步解决方案

1.1 XA与最后资源博弈

1.start MQ transaction
2.receive message
# 针对 DB 用 JTA 事务
3.start JTA transaction on DB
4.update DB
# DB 一阶段提交
5.phase-1 commit on DB transaction
# 该步出错时,由于DB还在XA的第一次提交预备状态,DB可回滚
6.commit MQ transaction  
# 等到MQ事务提交完成,才做DB二阶段提交
# 该步出错时,因为MQ不是XA方式,提交后无法回滚,虽然DB都可回滚
7.phase-2 commit on DB transaction

1.2 共享资源

适用场景

两个数据源可共享同一底层资源时。

如ActiveMQ使用DB作为底层资源存储,使用DB的connection控制事务提交,需要数据源支持指定底层资源存储方式。

1.3 最大努力一次提交

依次提交事务,可能会出错,尽量通过AOP或Listener实现事务直接的同步。

1.4 JMS最大努力一次提交+重试

适用场景:其中一个数据源是MQ,并且事务由读MQ消息开始。

利用MQ消息的重试机制,重试的时候需要考虑重复消息。

1.start message transaction
2.receive message
3.start database transaction
# 数据库操作出错,消息会被放回MQ,重试重新触发该方法
4.update database
5.commit database transaction
6.commit message transaction

这种时候没有问题,都能成功回滚。

1.start message transaction
2.receive message
3.start database transaction
4.update database
5.commit database transaction
# 提交MQ事务出错,消息放回MQ,重试重新触发该方法   
6.commit message transaction

DB 已经提交了,所以这时会重复 DB操作,因为DB transaction不是使用JTA事务管理,所以DB已经commit成功. 那如何避免呢,需要忽略重发消息,比如唯一性校验等手段。

1.5 链式事务管理

定义一个事务链,多个事务在一个事务管理器里依次提交。

依旧可能出错。

2 事务方案选型

业务一致性要求

  • 强一致性事务:JTA,性能最差、只适用于单个服务内。
  • 弱、最终一致性事务:最大努力一次提交、链式事务(设计相应的错误处理机制)

业务场景

  • MQ-DB:最大努力一次提交 + 重试
  • 多DB:链式事务管理

多数据源:链式事务、或其他事务同步方式

目录
相关文章
|
4月前
|
人工智能 Java Nacos
基于 Spring AI Alibaba + Nacos 的分布式 Multi-Agent 构建指南
本文将针对 Spring AI Alibaba + Nacos 的分布式多智能体构建方案展开介绍,同时结合 Demo 说明快速开发方法与实际效果。
3637 75
|
5月前
|
存储 安全 Java
管理 Spring 微服务中的分布式会话
在微服务架构中,管理分布式会话是确保用户体验一致性和系统可扩展性的关键挑战。本文探讨了在 Spring 框架下实现分布式会话管理的多种方法,包括集中式会话存储和客户端会话存储(如 Cookie),并分析了它们的优缺点。同时,文章还涵盖了与分布式会话相关的安全考虑,如数据加密、令牌验证、安全 Cookie 政策以及服务间身份验证。此外,文中强调了分布式会话在提升系统可扩展性、增强可用性、实现数据一致性及优化资源利用方面的显著优势。通过合理选择会话管理策略,结合 Spring 提供的强大工具,开发人员可以在保证系统鲁棒性的同时,提供无缝的用户体验。
118 0
|
6月前
|
监控 Java API
Spring Boot 3.2 结合 Spring Cloud 微服务架构实操指南 现代分布式应用系统构建实战教程
Spring Boot 3.2 + Spring Cloud 2023.0 微服务架构实践摘要 本文基于Spring Boot 3.2.5和Spring Cloud 2023.0.1最新稳定版本,演示现代微服务架构的构建过程。主要内容包括: 技术栈选择:采用Spring Cloud Netflix Eureka 4.1.0作为服务注册中心,Resilience4j 2.1.0替代Hystrix实现熔断机制,配合OpenFeign和Gateway等组件。 核心实操步骤: 搭建Eureka注册中心服务 构建商品
1079 3
|
4月前
|
负载均衡 Java API
《深入理解Spring》Spring Cloud 构建分布式系统的微服务全家桶
Spring Cloud为微服务架构提供一站式解决方案,涵盖服务注册、配置管理、负载均衡、熔断限流等核心功能,助力开发者构建高可用、易扩展的分布式系统,并持续向云原生演进。
|
9月前
|
人工智能 负载均衡 Java
Spring AI Alibaba 发布企业级 MCP 分布式部署方案
本文介绍了Spring AI Alibaba MCP的开发与应用,旨在解决企业级AI Agent在分布式环境下的部署和动态更新问题。通过集成Nacos,Spring AI Alibaba实现了流量负载均衡及节点变更动态感知等功能。开发者可方便地将企业内部业务系统发布为MCP服务或开发自己的AI Agent。文章详细描述了如何通过代理应用接入存量业务系统,以及全新MCP服务的开发流程,并提供了完整的配置示例和源码链接。未来,Spring AI Alibaba计划结合Nacos3的mcp-registry与mcp-router能力,进一步优化Agent开发体验。
3078 14
|
存储 Java 关系型数据库
在Spring Boot中整合Seata框架实现分布式事务
可以在 Spring Boot 中成功整合 Seata 框架,实现分布式事务的管理和处理。在实际应用中,还需要根据具体的业务需求和技术架构进行进一步的优化和调整。同时,要注意处理各种可能出现的问题,以保障分布式事务的顺利执行。
1309 160
|
11月前
|
存储 Java 文件存储
🗄️Spring Boot 3 整合 MinIO 实现分布式文件存储
本文介绍了如何基于Spring Boot 3和MinIO实现分布式文件存储。随着应用规模扩大,传统的单机文件存储方案难以应对大规模数据和高并发访问,分布式文件存储系统成为更好的选择。文章详细讲解了MinIO的安装、配置及与Spring Boot的整合步骤,包括Docker部署、MinIO控制台操作、Spring Boot项目中的依赖引入、配置类编写及工具类封装等内容。最后通过一个上传头像的接口示例展示了具体的开发和测试过程,强调了将API操作封装成通用工具类以提高代码复用性和可维护性的重要性。
2401 7
🗄️Spring Boot 3 整合 MinIO 实现分布式文件存储
|
资源调度 Java 调度
Spring Cloud Alibaba 集成分布式定时任务调度功能
定时任务在企业应用中至关重要,常用于异步数据处理、自动化运维等场景。在单体应用中,利用Java的`java.util.Timer`或Spring的`@Scheduled`即可轻松实现。然而,进入微服务架构后,任务可能因多节点并发执行而重复。Spring Cloud Alibaba为此发布了Scheduling模块,提供轻量级、高可用的分布式定时任务解决方案,支持防重复执行、分片运行等功能,并可通过`spring-cloud-starter-alibaba-schedulerx`快速集成。用户可选择基于阿里云SchedulerX托管服务或采用本地开源方案(如ShedLock)
458 1
|
资源调度 Java 调度
Spring Cloud Alibaba 集成分布式定时任务调度功能
Spring Cloud Alibaba 发布了 Scheduling 任务调度模块 [#3732]提供了一套开源、轻量级、高可用的定时任务解决方案,帮助您快速开发微服务体系下的分布式定时任务。
16220 108
|
存储 NoSQL Java
使用lock4j-redis-template-spring-boot-starter实现redis分布式锁
通过使用 `lock4j-redis-template-spring-boot-starter`,我们可以轻松实现 Redis 分布式锁,从而解决分布式系统中多个实例并发访问共享资源的问题。合理配置和使用分布式锁,可以有效提高系统的稳定性和数据的一致性。希望本文对你在实际项目中使用 Redis 分布式锁有所帮助。
892 5

热门文章

最新文章