SSM 如何使用 Saga 机制实现分布式事务?

news2025/1/19 17:02:24

SSM 如何使用 Saga 机制实现分布式事务?

在分布式系统中,事务管理一直是一个复杂的问题。传统的 ACID 事务只适用于单体应用,随着微服务架构的兴起,分布式事务成为了必须解决的问题。Saga 是一种解决分布式事务问题的机制,它通过将一个大事务分解为多个小事务并使它们顺序执行来保证分布式事务的一致性。本文将介绍如何使用 Saga 机制实现分布式事务。

在这里插入图片描述

什么是 Saga 机制?

Saga 是一种解决分布式事务问题的机制,它通过将一个大事务分解为多个小事务并使它们顺序执行来保证分布式事务的一致性。每个小事务都是一个本地事务,Saga 将这些本地事务组合成一个全局事务。如果某个本地事务失败,Saga 会通过执行补偿操作来回滚全局事务。Saga 机制的核心思路是将分布式事务分解成多个本地事务,这些本地事务可以跨越不同的服务,但是在一个事务期间内,它们必须遵循一致性规则。

SSM 如何使用 Saga 机制实现分布式事务?

SSM(Spring + Spring MVC + MyBatis)是一种常用的 Java 开发框架,它提供了完善的事务管理机制。使用 Saga 机制实现分布式事务需要满足以下条件:

  • 每个本地事务必须是独立的,并且可以回滚
  • Saga 必须能够在本地事务之间进行协调和通信
  • Saga 必须能够回滚全局事务

下面将介绍如何使用 SSM 框架和 Saga 机制实现分布式事务。

1. 引入依赖

首先需要引入以下依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
    <version>1.4.0</version>
</dependency>

这些依赖包括了 Seata 分布式事务框架,它提供了 Saga 机制的实现。

2. 配置 Seata

在使用 Seata 之前,需要在 Seata Server 中配置数据源和事务组。Seata Server 可以通过下载 Seata 发行版并解压来启动。配置文件路径为 conf/file.conf,示例如下:

store {
  mode = "db"
  db {
    driverClassName = "com.mysql.jdbc.Driver"
    url = "jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true"
    username = "root"
    password = "123456"
  }
}

service {
  vgroupMapping.{your-service-group} = "default"
}

config {
  ...
}

其中,store 部分配置了 Seata 的数据源信息;service 部分配置了事务组映射;config 部分配置了 Seata 的一些全局参数,例如超时时间等。

3. 配置 SSM

在 SSM 中使用 Seata 实现分布式事务,需要配置以下内容:

3.1 数据源

首先需要配置数据源,这里假设使用 MySQL 数据库。在 Spring 配置文件中添加以下内容:

<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://127.0.0.1:3306/test"/>
    <property name="username" value="root"/>
    <property name="password" value=""/>
</bean>

3.2 事务管理器

接下来需要配置事务管理器,这里使用 Spring 提供的 JpaTransactionManager。在 Spring 配置文件中添加以下内容:

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

3.3 Seata 配置

在 Spring 配置文件中添加以下内容:

<bean id="seataGlobalTransactionScanner" class="io.seata.spring.annotation.GlobalTransactionScanner">
    <constructor-arg name="applicationId" value="{your-service-group}"/>
    <constructor-arg name="txServiceGroup" value="default"/>
</bean>

其中,applicationId 配置为你的服务组名,txServiceGroup 配置为 Seata中定义的事务组名。

4. 实现分布式事务

在 SSM 中使用 Saga 机制实现分布式事务,需要将一个大事务分解为多个小事务,并使它们顺序执行。每个小事务都是一个本地事务,Saga 将这些本地事务组合成一个全局事务。如果某个本地事务失败,Saga 会通过执行补偿操作来回滚全局事务。

下面是一个示例代码,演示了如何使用 Saga 机制实现一个简单的分布式事务。

4.1 定义本地事务

首先需要定义两个本地事务:

@Service
public class OrderService {
    
    @Autowired
    private OrderMapper orderMapper;
    
    @GlobalTransactional
    public void createOrder(Order order) {
        orderMapper.createOrder(order);
    }
    
    @GlobalTransactional
    public void cancelOrder(Long orderId) {
        orderMapper.cancelOrder(orderId);
    }
    
}
#### 4.2 定义 Saga

然后定义 Saga,将这两个本地事务组合成一个全局事务:

```java
@Saga
@Service
public class OrderSaga {
    
    @Autowired
    private OrderService orderService;
    
    @StartSaga
    @SagaTcc
    public void createOrderSaga(Order order) {
        orderService.createOrder(order);
    }
    
    @SagaTcc
    public void cancelOrderSaga(Order order) {
        orderService.cancelOrder(order.getId());
    }
    
    @EndSaga
    public void endSaga() {
        // do nothing
    }
    
}

其中,@Saga 注解表示这是一个 Saga 类;@StartSaga 注解表示这是一个 Saga 的起点;@SagaTcc 注解表示这是一个 Saga 的一部分,它执行一个本地事务。

4.3 触发 Saga

最后,在业务中触发 Saga:

@Service
public class OrderBusinessService {
    
    @Autowired
    private OrderSaga orderSaga;
    
    public void createOrder(Order order) {
        orderSaga.createOrderSaga(order);
    }
    
    public void cancelOrder(Order order) {
        orderSaga.cancelOrderSaga(order);
    }
    
}

其中,createOrder 方法触发了一个 Saga,执行创建订单的本地事务;cancelOrder 方法触发了另一个 Saga,执行取消订单的本地事务。

当一个 Saga 被触发时,Seata 会在全局事务上下文中创建一个事务 ID,并将这个事务 ID 传递给 Saga。在 Saga 的执行过程中,Seata 会将事务 ID 传递给每个本地事务,以保证它们在同一个全局事务中运行。如果某个本地事务失败,Seata 会回滚全局事务,并执行相应的补偿操作。

总结

使用 Saga 机制实现分布式事务可以提高系统的可靠性和可扩展性,但也增加了系统的复杂性。在实际应用中,需要根据实际情况选择合适的分布式事务解决方案。如果使用 SSM 框架,可以通过引入 Seata 分布式事务框架,使用 Saga 机制实现分布式事务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/574384.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

聊聊API 安全

API 安全的现状 随着互联网的高速发展和技术的日趋成熟&#xff0c;人们在享受技术所带来的便利之时&#xff0c;也开始关注技术层面的安全问题。 近年来&#xff0c;应用市场成为各大互联网平台企业的最爱&#xff0c;Facebook、Twitter、新浪微博、微信公众号、抖音等均使用了…

5月面试太难,吃透这份软件测试面试笔记后,成功跳槽涨薪30K

5月开始&#xff0c;生活工作渐渐步入正轨&#xff0c;但金三银四却没有往年顺利。昨天跟一位高级架构师的前辈聊天时&#xff0c;聊到今年的面试。有两个感受&#xff0c;一个是今年面邀的次数比往年要低不少&#xff0c;再一个就是很多面试者准备明显不足。不少候选人能力其实…

ThreadLocal的应用

1. ThreadLocal 是什么 JDK 对ThreadLocal的描述为&#xff1a; 此类提供线程局部变量。这些变量与普通变量的不同之处在于&#xff0c;每个访问一个变量的线程&#xff08;通过其get或set方法&#xff09;都有自己的、独立初始化的变量副本。ThreadLocal 实例通常是类中的私有…

ReentrantLock 和 synchronized 关键字有什么区别?

ReentrantLock 和 synchronized 关键字有什么区别&#xff1f; 在 Java 中&#xff0c;有两种常用的锁机制&#xff1a;ReentrantLock 和 synchronized 关键字。它们都可以用来实现线程同步&#xff0c;但在具体的使用上有一些区别。本文将介绍 ReentrantLock 和 synchronized…

如何用Thanos 和 Prometheus 打造一个高可用的K8S监控系统

概 述 对于弹性伸缩和高可用的系统来说&#xff0c;一般有大量的指标数据需要收集和存储&#xff0c;如何为这样的系统打造一个监控方案呢&#xff1f;本文介绍了如何使用 ThanosPrometheusGrafana 构建监控系统。 集群容量概览 用户故事 直到今年 1 月&#xff0c;我一直在…

C#小项目之记事本

C#小项目之记事本 子窗体设计 frmChild.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; …

第 2 章 Servlet 编程

文章目录 第 2 章 Servlet 编程2.1 Servlet 简介2.2 Servlet 基础2.2.1 用记事本写一个 Servlet2.2.2 Servlet 体系结构2.2.3 Servlet 接口2.2.4 Servlet 生命周期2.2.5 Servlet 生命周期示例 2.3 Servlet API编程常用接口和类2.3.1 GenericServlet 类2.3.2 HttpServlet类2.3.3…

使用object.defineProperty来更新数据示例

Object.defineProperty() 方法会直接在一个对象上定义一个新属性&#xff0c;或者修改一个对象的现有属性&#xff0c;并返回此对象。 Object.defineProperty&#xff08;&#xff09;可以为对象的属性添加特性&#xff0c;每一个被添加过的属性&#xff0c;都会拥有属于自己的…

公司来了个00后,真是卷死了呀,辞职信已经写好了·····

人们都说00后躺平了&#xff0c;但是有一说一&#xff0c;该卷的还是卷。这不&#xff0c;三月份春招我们公司来了个00后&#xff0c;工作没两年&#xff0c;跳槽到我们公司起薪20K&#xff0c;都快接近我了。 后来才知道人家是个卷王&#xff0c;从早干到晚就差搬张床到工位睡…

chatgpt赋能python:Python单行命令:while

Python单行命令&#xff1a;while 介绍 在Python中&#xff0c;while循环是一种重复执行代码块的结构&#xff0c;只要满足循环条件&#xff0c;就会一直循环下去。而单行命令则是指一行代码就完成了某个任务。在Python语言中&#xff0c;我们可以使用单行命令在 while循环中…

springcloud高频面试题

springcloud的组件有哪些 注册中心&#xff1a;euraka、nacos、zookeeper 注册中心及配置中心&#xff1a;nacos 远程调用&#xff1a;feign、dubbo 负载均衡&#xff1a;ribbon 服务熔断&#xff1a;hystrix、sentinel 网关&#xff1a;zuul、gateway eureka注册中心的作用 …

JAVA面试八股整理——基础部分

JAVA 基础 JVM JDK JRE JVM java虚拟机&#xff0c;针对不同的系统&#xff0c;使用相同的字节码会给出相同结果。一次编译&#xff0c;随处可运行 JDK Java SDK 提供给开发者使用&#xff0c;创建和编译Java程序。包含了JRE&#xff0c;同时包含了其它工具&#xff08;jav…

Deepin 23的最佳新功能和亮点

Deepin是一个基于Linux的操作系统&#xff0c;以其美观、简洁和易用的用户界面而闻名。Deepin 23是Deepin操作系统的最新版本&#xff0c;引入了许多令人兴奋的新功能和亮点&#xff0c;为用户提供了更好的体验和更多的功能。 本文将详细介绍Deepin 23的最佳新功能和亮点。 1…

教你彻底卸载MySQL 并重装(保姆级教程 )

前言&#xff1a;都是自己踩过的坑&#xff08;其他博主也有&#xff0c;不过我的特殊&#xff0c;按步骤走完重新安装仍要输入原密码&#xff0c;本篇主要解决和我问题类似的情况&#xff09;&#xff0c;跟着以下步骤走就行。 步骤一&#xff1a;关闭MySQL服务 右击【计算机】…

@Transactional @Aysnc 循环依赖 事务同步问题

文章目录 学习链接场景最初版本TestControllerTestService问题 Lazy版本 事务同步报错版本&#xff1a;TestServiceLazy正常启动版本&#xff08;有问题&#xff09;Lazy 注册事务同步 学习链接 Async学习及循环依赖 场景 我们要做的事情很简单&#xff1a; 现在我们需要…

高校智能用电管理系统的应用探讨

摘 要&#xff1a;随着现代科学技术的发展&#xff0c;在高校中开始广泛应用智能化技术&#xff0c;改善学生宿舍的用电管理模式&#xff0c;提高宿舍的管理水平&#xff0c;有利于实现高校宿舍用电管理的科学化。本文主要阐述传统高校宿舍用电管理模式&#xff0c;设计高校智能…

tektronix泰克TDS3054B数字荧光示波器

TDS3054B示波器体积小巧、便于携带、可用电池供电&#xff0c;所以可在任何需要的地方使用。安装电池 后&#xff0c;其重量还不到5 公斤。即便是在现场工作&#xff0c;也可通过选购的插入式热敏打印机当场打印测量 结果。 用户还可通过选购的应用模块轻而易举地使TDS3000B 系…

Web3小白科普系列:加密社区行业黑话全解(第一弹)

加密货币的快速发展创造了属于自己的全新语言&#xff0c;其中充满了黑话和首字母缩写&#xff0c;可能会让新手不知所措。本期《Web3小白科普系列&#xff1a;加密社区行业黑话全解》旨在解释加密世界中经常使用的、旁人难以解读的术语。我们将深入探究流行俚语的起源和含义&a…

专转本大忌,老实说这样备考真的考不上

&#xff08;1&#xff09;目标院校定太高&#xff0c;报考全凭主观臆断&#xff0c;没有深入了解学校专业和今年的考情&#xff0c;结果自身实力不够导致错失升本的机会。 &#xff08;2&#xff09;盲目追求学习时间却不追求效率&#xff0c;经常熬夜通宵学习&#xff0c;结…

开发工具---Eclipse 教程Ⅰ

Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。 Eclipse 是 Java 的集成开发环境&#xff08;IDE&#xff09;&#xff0c;当然 Eclipse 也可以作为其他开发语言的集成开发环境&#xff0c;如C&#xff0c;C&#xff0c;PHP&#xff0c;和 Ruby 等。 Eclipse 附带…