跨多个服务的事务操作是一种疯狂的方法

跨多个服务的事务操作是一种疯狂的方法

团队在微服务环境中必须处理的众多复杂问题之一就是事务。跨越多个微服务的事务。与单体应用程序不同,单体应用程序的事务通常使用单个数据库和 @transactional
进行管理 注解,在微服务中,每个服务往往都有自己的数据库,使得分布式事务变得更加复杂。这是有关如何在 spring boot 中有效处理这些分布式事务的指南。

首先,让我们先就什么是交易达成一致。

事务是计算或数据库环境中的一个工作单元,被视为单个不可分割的操作。它代表一系列必须一起成功或一起失败的操作或步骤,即使在发生意外事件(例如断电或网络故障)时也能确保数据的一致性和完整性。

在数据库上下文中,事务可能涉及多个查询,例如创建、更新或删除记录。交易通常遵循四个基本属性,称为 acid 属性:

a. 原子性 – 事务中的所有操作都被视为单个单元。要么所有操作成功,要么全部失败。

b. 一致性 – 事务将系统从一种有效状态转移到另一种有效状态,从而保持数据有效性。

c. 隔离 – 事务是隔离执行的,这意味着中间状态对其他事务不可见。

d. 持久性 – 事务一旦提交,其更改就是永久性的,并且在系统崩溃时也能幸存。

一个短篇故事

在一个繁忙的电子商务应用程序中,想象一下客户 alice 订购了一台新笔记本电脑、一个配件和快递。以下是她的订单如何在由 ordersagaorchestrator 管理的系统中流动的幕后故事。

在一个繁忙的电子商务应用程序中,想象一下客户 alice 订购了一台新笔记本电脑、一个配件和快递。以下是她的订单如何在由 ordersagaorchestrator 管理的系统中流动的幕后故事。

alice 输入付款和送货信息后点击“立即订购”。此操作启动了一个称为传奇的流程,这是一系列精心策划的交易,以确保她的订单从头到尾得到正确处理。

第 1 步:付款处理
saga 编排器首先检查 paymentservice,发起调用以从 alice 的帐户中扣除所需的金额。调用 paymentservice.processpayment() 方法,授权 alice 付款。

第2步:库存预订
一旦付款成功,协调器就会转移到 inventoryservice,在那里为 alice 保留特定的笔记本电脑型号和配件。此预订步骤至关重要,以便在订单仍在处理期间,库存不会售完或交给其他客户。

第 3 步:发货启动
成功预订库存后,saga 协调器将联系 shippingservice。在这里,shippingservice.initiateshipping() 启动物流,确保物品包装好并准备好运送到 alice 的地址。

处理失败:补偿逻辑

但是在分布式环境中,任何一步都可能出错。如果由于物流错误导致发货启动失败,或者由于库存差异而实际上无法履行库存怎么办?协调器已准备好补偿策略。

如果抛出异常,协调器将启动补偿事务以回滚整个过程,因此 alice 不会为她不会收到的物品付费:

3.1。取消发货 – 协调器调用shippingservice.cancelshipping(),停止发货。

3.2。释放库存 – 然后触发 inventoryservice.releaseinventory(),释放 alice 的保留物品,以便其他客户可以购买它们。

3.3。退款 – 最后,它调用 paymentservice.refund() 来退还 alice 的付款,确保她不会为订单付费。

最后,这个精心策划的传奇确保了 alice 的体验流畅且一致,如果出现任何问题,都会以维护系统完整性的方式解决。这就是微服务中分布式事务和补偿逻辑的魔力。

现在我们知道了什么是事务并了解了事务可能有用的现实场景,让我们深入研究如何在分布式环境中实现此功能。

团队可以使用一些关键方法来解决这个问题

1。 saga 模式: saga 模式是微服务架构中处理分布式事务最广泛使用的模式之一。传奇是每个服务独立执行的本地事务序列。 saga 中的每一步都会通过一个操作来补偿,如果 saga 失败,该操作会撤消该步骤。

saga 模式可以通过两种主要方式实现:

a。 基于编排的 saga: 事务中涉及的每个服务都会侦听事件并执行其事务。完成后,它会发出一个事件来触发传奇中的下一步。如果某个步骤失败,则会触发补偿事件以撤消之前的步骤。

b。 基于编排的 saga: 集中式服务(saga 编排器)协调 saga 的步骤。它确定操作顺序并管理发生故障时的补偿。

2。两阶段提交(2pc): 虽然两阶段提交协议通常用于单体系统,但它可以通过 atomikos 或 bitronix 等分布式事务管理器跨分布式系统使用。但是,我不推荐这种方法,因为它在微服务上下文中存在一些限制,因为它会导致高延迟并且容错能力较差。如果我是你,我通常会避免这种方法,而选择 saga 模式。

3。事件驱动架构: 使用事件驱动方法,服务通过事件进行通信,特别适合处理分布式事务。这种方法与 saga 模式非常吻合。每个服务独立执行其事务,然后发出一个事件以通知其他服务有关结果。这些事件可以使用 apache kafka、rabbitmq 或其他消息代理来处理。

现在,让我们看看它在代码中是如何工作的。

saga 模式有多种风格,但在本文中,我将尝试在 spring boot 中实现基于编排的 saga 模式:

第 1 步: 定义 saga orchestrator:
在这里,我将创建一个简单的服务来充当协调器,负责协调事务。

该服务将定义传奇的流程,以正确的顺序调用每个服务,并在需要时处理补偿事务。

@servicepublic class ordersagaorchestrator {    @autowired    private paymentservice paymentservice;    @autowired    private inventoryservice inventoryservice;    @autowired    private shippingservice shippingservice;    public void createordersaga(order order) {        try {            paymentservice.processpayment(order.getpaymentdetails());            inventoryservice.reserveinventory(order.getitems());            shippingservice.initiateshipping(order.getshippingdetails());        } catch (exception e) {            // compensation logic            shippingservice.cancelshipping(order.getshippingid());            inventoryservice.releaseinventory(order.getitems());            paymentservice.refund(order.getpaymentid());        }    }}

登录后复制

第 2 步: 在每个服务中创建本地事务和补偿方法:

每个服务都应该有自己的事务来完成其在传奇中的步骤,并在需要时使用另一个事务来补偿它。这是大概的结构。

@servicepublic class paymentservice {    @transactional    public void processpayment(paymentdetails details) {        // perform payment logic    }    @transactional    public void refund(string paymentid) {        // perform refund logic    }}

登录后复制

第 3 步: 基于事件的通信(可选,用于编排):每个服务都可以发出事件来通知其他人交易的结果。

public class paymentservice {    private final applicationeventpublisher eventpublisher;    public paymentservice(applicationeventpublisher eventpublisher) {        this.eventpublisher = eventpublisher;    }    public void processpayment(paymentdetails details) {        // process payment        eventpublisher.publishevent(new paymentprocessedevent(this, details));    }}

登录后复制

第 4 步: 采取措施保证数据一致性:使用幂等性检查来确保 saga 中的每个步骤仅执行一次。这在分布式系统中很重要,因为网络故障或重试可能会导致重复请求。

第 5 步: 使用消息代理来提高可靠性:如果您使用事件来管理传奇,可以使用像 rabbitmq 的 kafka 这样的消息代理持久性,并且可以在服务暂时不可用时缓冲事件。

第 6 步: 错误处理和重试: 将错误处理和重试逻辑合并到您的协调器和各个服务中以处理临时故障。 spring retry 在这里很有用,因为它可以在可配置策略中自动重试失败的操作。

@Retryable(value = {RemoteServiceException.class}, maxAttempts = 3, backoff = @Backoff(delay = 2000))public void reserveInventory(List items) {    // Attempt to reserve inventory}

登录后复制

结论

微服务中的分布式事务具有挑战性,但通过使用 saga(尤其是编排)和事件驱动通信等模式,您可以实现可靠且可扩展的解决方案。

spring boot 通过提供对事务管理、事件发布以及与消息代理集成的支持,使这一切变得更容易。

最后,这个精心策划的传奇确保了 alice 的体验流畅且一致,如果出现任何问题,都会以维护系统完整性的方式解决。这就是微服务中分布式事务和补偿逻辑的魔力。

以上就是跨多个服务的事务操作是一种疯狂的方法的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2589986.html

(0)
上一篇 2025年3月6日 16:21:37
下一篇 2025年2月24日 03:31:18

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • RabbitMQ 与 Kafka:为您的 Java 应用程序选择正确的消息代理

    比较 RabbitMQ 和 Kafka: 在根据您的消息代理需求选择 RabbitMQ 和 Kafka 时,了解它们的独特优势和最佳用例至关重要。 RabbitMQ 是一个传统的消息代理,它使用推送模型向消费者传递消息。它以其灵活性而闻名,…

    2025年3月6日
    200
  • 过载时施加背压:管理系统稳定性

    简介 在分布式系统中,如果应用程序承受的数据或请求超出其处理能力,可能会导致故障、性能下降,甚至完全中断。这就是背压概念发挥作用的地方。 背压是一种用于管理和调节系统中组件之间的数据流的技术。它确保当下游服务不堪重负时,上游服务调整数据传输…

    2025年3月6日
    200
  • RabbitScout:用于管理 RabbitMQ 的现代开源仪表板

    您是否曾经希望有一种超越默认管理 ui 的更直观、更具视觉吸引力的方式来管理 rabbitmq?尽管我非常欣赏 rabbitmq 的稳健性,但在日常监控和操作方面,现有界面可能会让人感觉有点过时。这就是我构建 rabbitscout 的原因…

    2025年3月6日
    200
  • JMS如何实现消息通信?

    深入了解JMS消息通信的实现方式 JMS(Java消息服务)仅仅定义了消息通信的接口规范,具体的实现则依赖于不同的JMS提供商。 那么,JMS是如何实现消息通信的呢? JMS的实现主要通过以下几种方式: 消息中间件(Message Brok…

    2025年3月6日
    100
  • JMS消息通信:接口与实现详解

    深入理解JMS消息通信机制 核心问题: JMS仅仅是一个规范吗?它如何具体实现消息传递? 解答: JMS (Java消息服务) 并非一个具体的中间件产品,而是一个Java API规范。它定义了一套标准接口和协议,允许Java应用程序与各种消…

    2025年3月6日
    200
  • Java初学者如何搭建企业级后端?

    Java企业级微服务后端开发详解:初学者指南 构建健壮的Java企业级微服务后端需要选择合适的框架和技术。本文将为Java初学者提供一个全面的指南,涵盖后端框架搭建和开源解决方案的选择。 核心技术栈 一个高性能的Java企业级后端通常需要以…

    2025年3月6日
    200
  • c++属于前端还是后端

    C++ 既可用于前端(用户界面创建)也可用于后端(服务器端逻辑处理),因为它强大且高效,支持多范例编程。决定因素包括应用类型、性能要求和开发团队技能。 C++:前端还是后端? C++ 既可以用于前端开发,也可以用于后端开发。因此,它不属于前…

    2025年3月6日
    200
  • 并发编程的未来趋势是什么?新技术和范例有哪些?

    并发编程的未来趋势:新技术和范例 在当今快节奏的世界中,并发编程已经成为开发健壮、高效应用程序的关键。随着技术的不断进步,并发编程的未来呈现出令人兴奋的前景,带来了新的技术和范例,以应对不断增长的挑战。 分布式计算 分布式计算是利用分布在多…

    2025年3月6日
    200
  • 模板化编程与代码生成器之间的关系?

    模板化编程和代码生成器通过自动化代码生成,提高了开发效率和代码质量。模板化编程使用类型占位符定义通用代码,而代码生成器根据模板生成实际代码。它们密切相关,其中代码生成器通常利用模板化编程技术实现,而模板化编程提供了抽象层,使开发人员可以编写…

    2025年3月6日
    200
  • C++云数据处理:大数据分析与机器学习

    在云计算处理大数据时,c++++ 凭借以下好处成为有力工具:高性能:编译型语言,直接转换为机器代码,实现高效运行。可扩展性:大型社区和丰富库,开发和维护大规模并行应用程序更轻松。灵活性:允许对并行和内存管理进行细粒度控制,优化应用程序性能,…

    2025年3月6日
    200

发表回复

登录后才能评论