分布式事务理论及Seata实践

分布式事务简介

事务是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。事务的四个特征(ACID)

  • 原子性(Atomicity): 指一组操作要么全部执行,要么全部不执行。在事务执行过程中,如果出错则会滚到事务开始前的状态,所有操作像一个原子,不可拆分。
  • 一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。
  • 隔离性(Isolation):同一时间,只允许一个事务操作同一条数据,并且操作对其他事务不可见,不同事务之间也不会有干扰,
  • 持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。

传统的单体应用借助关系数据库的ACID特性能很好的保证数据一致性,但是随着系统的发展,由单体应用向分布式、微服务的演变,传统的事务无法协调多个服务、多个数据库之间的事务,是之达到统一提交或统一回滚状态。

分布式事务是指事务的参与者、资源服务器以及事务管理器分别位于不同的分布式系统的不同结点之上,一次分布式事务涉及到多个系统、数据库之间的协调,保证分散在各结点的事务操作要么全部成功,要么全部失败。

分布式事务理论

CAP理论

CAP理论对分布式系统特性做了高度抽象,形成了三个指标:

  • 一致性(Consistency):多个结点的数据需时刻保持一致,用户无论访问哪个结点读取的数据是一致的(强一致性)。
  • 可用性(Availability):指任何来自客户端的请求,不管访问哪个非故障结点,都能得到响应数据,但并不保证是最新的数据。可用性的两个关键一个是合理的时间,一个是合理的响应。
  • 分区容错性(Partition Tolerance):将服务分散在多个节点上,当节点间出现任务数量的消息丢失或高延迟的时候,系统任能持续的工作。

image-20240106100120139

在分布式系统中,只要有网络交互就一定存在延迟和数据丢失,这是我们必须接受的,同时还要保证系统不能挂掉。节点间的分区故障是必然存在的,也就是说分区容错性(P)是必须要保证的。现在就只剩下一致性(C)和可用性(A)之间选择一个了。

当选择了一致性(C),系统能保证读取到最新的数据,但节点之间数据同步需要时间,就会导致在读取数据时发生阻塞而超时,为了不破坏一致性,可能会因为无法响应最新数据而返回错误信息。

当选择了可用性(A),系统将始终响应客户端的查询,返回特点的信息,但如果发生网络分区、或者数据延迟,返回的数据并不一定是全局最新数据。

BASE理论

由于CAP理论我们只能在C、A、P中选择其中两个。BASE理论是对CAP中一致性和可用性权衡的结果。它的核心思想是,如果非必须,不推荐使用强一致性,鼓励优先考虑可用性,根据业务的场景来实现弹性的基本可用,以及实现数据最终一致性。

  • BA:Basic Available基本可用,当系统出现不可预知的故障,允许损失部分可用性,但不是完全不可用。

  • S:Soft State柔性状态,数据存在一个中间状态,并该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时。

  • E:Eventual Consisstency最终一致性,经过一段时间的同步后,最终能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。

分布式事务解决方案

两阶段提交(2PC)
  • 事务发起阶段:

事务的发起者提出一个request(比如用户下单购买某个商品),要求其依赖的服务(事务的执行者)本地执行业务逻辑。执行成功本地事务不提交但要告诉发起者本地已经执行成功;执行失败执行者告诉发起者本地作业执行失败

  • 事务提交/回滚阶段:

事务发起者根据事务发起阶段收集到的信息决定提交/回滚

如果全部执行者都反馈成功那么发起者通知所有执行者提交事务

如果存在执行者反馈失败,则发起者通知所有参与者取消事务

image-20240107161725860

三阶段提交(3PC)
  • CanCommit(询问阶段):

事务协调者向参与者发送事务执行请求,询问是否可以完成指令,参与者只需要回答是不是即可,不需要做正真的事务操作,这个阶段会有超时终止机制。

  • PreCommit(准备阶段):

事务协调者会根据参与者的反馈结果决定是否继续执行,如果在询问阶段所有参与者都返回可以执行操作,则事务协调者会向所有参与者发送PreCommit请求,参与者收到请求后会写redo和undo日志,执行事务操作但是不提交事务,然后返回ACK响应等待事务协调者的下一步通知。如果询问阶段任意参与者返回不能执行操作的结果,那么事务协调者会向所有参与者发送事务中断请求。

  • DoCommit(提交或回滚阶段):

这个阶段也会存在两种结果,根据上一步骤的执行结果来决定DoCommit的执行方式。如果每个参与者在PreCommit阶段都返回成功,那么事务协调者会向所有的参与者发起事务提交指令。反之,如果参与者中的任一个参与者返回失败,那么事务协调者就会发起中转指令来回滚事务。

image-20240107162021011

TCC

TCC是将事务分为Try(尝试)、Confirm(确认)和Cancel(取消)三个阶段。每个阶段有开发者自己控制,避免了长事务的问题。

image-20240107162732336

TCC事务模式需要考虑下面几个问题:

  • 空回滚:当某分支事务的try阶段阻塞时,可能导致全局事务超时而触发二阶段的cancel操作。在未执行try操作时先执行了cancel操作,这时cancel不能做回滚,就是空回滚

  • 悬挂:对于已经空回滚的业务,如果以后继续执行try,就永远不可能confirm或cancel,这就是业务悬挂

  • 幂等:Confim、Cancel阶段不论网络原因或者业务异常,都会根据日志记录重复执行操作,所以需要保持接口的幂等性,也就是最多执行一次

Seata框架介绍

Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。

image-20240107164948026

Seata由三种角色组成:

  • TC (Transaction Coordinator) - 事务协调者

维护全局和分支事务的状态,驱动全局事务提交或回滚。

  • TM (Transaction Manager) - 事务管理器

定义全局事务的范围:开始全局事务、提交或回滚全局事务。

  • RM (Resource Manager) - 资源管理器

管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

XA模式

XA 规范 是 X/Open 组织定义的分布式事务处理(DTP,Distributed Transaction Processing)标准,XA 规范 描述了全局的TM与局部的RM之间的接口,几乎所有****主流的数据库****都对 *XA 规范* 提供了支持。

1 TM负责定义全局事务的边界,向TC申请,开启一个全局事务;

2 全局事务创建成功后,生成全局唯一的XID;

3 XID会在微服务请求链路上下文中传播;

4 RM向TC注册分支事务,并归属到XID对应的全局事务进行调度;

5 TM向TC发起相应XID的全局事务提交或回滚决议;

6 TC完成对XID管理的全部分支事务提交或回滚的调度;

我们看下下面的demo,有order服务负责创建订单,并且通过Fegin调用库存服务扣库存,如果库存不足则回滚。

seata-order

    @GlobalTransactional(rollbackFor = {Exception.class})
    @Transactional
    public String createOrder(String userId, String itemId, Integer num) {

        Order order = new Order();
        order.setUserId(userId);
        order.setItemId(itemId);
        order.setNum(num);
        orderRepository.save(order);

        // 扣除库存
        inventoryFeign.adjust(itemId, num);
        return "创建成功";
    }

seata-inventory

public void adjust(String itemId, Integer num) {
       
        Inventory inventory = inventoryDao.findByItemId(itemId);

        if(inventory.getInventory() < num){
            throw new RuntimeException("库存不足");
        }
        inventory.setInventory(inventory.getInventory() - num);

        inventoryDao.save(inventory);

    }

库存表中有商品编号为10000的商品,库存为10。以debug的方式启动服务,在扣库存的地方打上端点,你会发现在扣完库存,库存的数量并没有减少,订单也没用创建,并且行记录也被锁住,直到事务提交,才能看到订单创建和库存扣减,如果扣除不足,订单也会回滚。

image-20240107082151767

前面我们提到过,AX是基于数据库的事务特征,属于两阶段提交,所以在整体事务提交前,各服务数据不可见。

XA模式的优点:

  • 事务的强一致性,满足ACID原则。

  • 常用数据库都支持,实现简单,并且没有代码侵入

XA模式的缺点:

  • 性能较差,因为一阶段需要锁定数据库资源,等待二阶段结束才释放,所以性能较差
  • 依赖关系型数据库实现事务。NoSQL参与不进来
AT模式

AT模式是基于两阶段协议的演变:

  • 一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。
  • 二阶段:
    • 提交异步化,非常快速地完成。
    • 回滚通过一阶段的回滚日志进行反向补偿。

修改为AT模式只需要修改配置:

seata.dataSourceProxyMode=AT
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`)
) E

AT模式需要新增一张undo_log表,用来记录执行SQL的回滚SQL,比如业务执行了INSERT操作,就会记录一下对应的DELETE语句。所以AT模式下是不依赖与数据库的事务。

AT模式的优点:

  • 一阶段完成直接提交事务,释放数据库资源,性能比较好
  • 利用全局锁实现读写隔离
  • 没有代码侵入,框架自动完成回滚和提交

AT模式的缺点:

  • 两阶段之间属于软状态,属于最终一致
  • 框架的快照功能会影响性能,但比XA模式要好很多
TCC模式

TCC 模式,不依赖于底层数据资源的事务支持:

  • 一阶段 prepare 行为:调用 自定义 的 prepare 逻辑。
  • 二阶段 commit 行为:调用 自定义 的 commit 逻辑。
    放数据库资源,性能比较好
  • 利用全局锁实现读写隔离
  • 没有代码侵入,框架自动完成回滚和提交

AT模式的缺点:

  • 两阶段之间属于软状态,属于最终一致
  • 框架的快照功能会影响性能,但比XA模式要好很多
TCC模式

TCC 模式,不依赖于底层数据资源的事务支持:

  • 一阶段 prepare 行为:调用 自定义 的 prepare 逻辑。
  • 二阶段 commit 行为:调用 自定义 的 commit 逻辑。
  • 二阶段 rollback 行为:调用 自定义 的 rollback 逻辑。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FineBI实战项目一(3):Kettle实现ETL到数据仓库

目前&#xff0c;finebi_shop_bi 中是没有任何数据的&#xff0c;是一个空的数据库。而后续我们的所有数据分析都将在该数据库中进行。我们第一件事情就是要将 「finebi_shop」数据库中的所有表抽取到「finebi_shop_bi」数据库中。要抽取并装载数据到「finebi_shop_bi」中&…

超维空间M1无人机使用说明书——51、ROS无人机使用AR二维码识别与定位

引言&#xff1a;二维码识别与定位是指ROS通过创建AR标签并且对AR标签进行识别&#xff0c;标签可以由自己任意创建&#xff0c;具体方法会在文中给出&#xff0c;摄像头可以通过识别AR标签大小和姿态获取到标签对应的ID和位置等信息&#xff0c;实现识别与定位 注意&#xff…

Qt/QML编程学习之心得:Linux下Thread线程创建(26)

GUI设计中经常为了不将界面卡死,会用到线程Thread,而作为GUI设计工具,Qt也提供了一个这样的类,即QThread。 QThread对象管理程序中的一个控制线程。线程QThread开始在run()中执行。默认情况下,run()通过调用exec()启动事件循环,并在线程内运行Qt事件循环。 也可以通过…

Camtasia2024苹果Mac电脑版(屏幕录制剪辑软件)

Camtasia Mac2024免费版是一款由TechSmith公司官方进行汉化推出的最新版本&#xff0c;借助Camtasia&#xff0c;您可以轻松记录屏幕并创建优美&#xff0c;专业的视频。记录所有内容-您的整个屏幕或只是一个窗口。或者&#xff0c;添加您已经拥有的视频&#xff0c;图像&#…

python 文件

open """ def open(file: FileDescriptorOrPath, //路径mode: OpenTextMode "r", //设置打开文件的模式 r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 w 打开一个文件只用写入。如果该文件已存在则打开文件&#…

一文讲透Python数据分析可视化之直方图(柱状图)

直方图&#xff08;Histogram&#xff09;又称柱状图&#xff0c;是一种统计报告图&#xff0c;由一系列高度不等的纵向条纹或线段表示数据分布的情况。一般用横轴表示数据类型&#xff0c;纵轴表示分布情况。通过绘制直方图可以较为直观地传递有关数据的变化信息&#xff0c;使…

【Python从入门到进阶】46、58同城Scrapy项目案例介绍

接上篇《45、Scrapy框架核心组件介绍》 上一篇我们学习了Scrapy框架的核心组件的使用。本篇我们进入实战第一篇&#xff0c;以58同城的Scrapy项目案例&#xff0c;结合实际再次巩固一下项目结构以及代码逻辑的用法。 一、案例网站介绍 58同城是一个生活服务类平台&#xff0c…

msckf_vio在ubuntu20.04中的编译

1.新建catkin workspace文件夹&#xff0c;并在其中新建src文件夹&#xff0c;并将源码clone至src内。 源码地址&#xff1a;https://github.com/KumarRobotics/msckf_vio 目录层级示意如下&#xff0c;build和devel不必新建&#xff0c;后续指令会自动新建。 2. 在编译之前…

java CAS

CAS 在高并发场景&#xff0c;可以使用加锁 或者CAS来保证原子性&#xff0c;但是加锁是很重量级的操作&#xff0c;CAS类似于乐观锁CAS &#xff08; Compare and swap &#xff09;比较并交换&#xff0c;是实现并发算法时常用到的技术&#xff0c;包含三个操作数&#xff1…

LVGL的List控件的触摸按键和实体按键的处理

在LVGL的List控件使用过程中&#xff0c;虽然通过触摸按键选择item&#xff0c;但是有些场景需要实体按键选取item&#xff0c;但是LVGL 的V8.3中没有像Emwin那样有函数选择list item的函数。LVGL中List引入了Group的概念&#xff0c;把列表项都添加到同一个group中。然后通过更…

Linux Capabilities 基础概念与基本使用

目录 1. Linux capabilities 是什么&#xff1f; 2. capabilities 的赋予和继承 线程的 capabilities Permitted* 允许 Effective* 有效 Inheritable* 遗传 Bounding&#xff08;集合&#xff09; Ambient 文件的 capabilities Permitted Inheritable Effective 3…

2.4 DEVICE GLOBAL MEMORY AND DATA TRANSFER

在当前的CUDA系统中&#xff0c;设备通常是带有自己的动态随机存取存储器&#xff08;DRAM&#xff09;的硬件卡。例如&#xff0c;NVIDIA GTX1080具有高达8 GB的DRAM&#xff0c;称为全局内存。我们将互换使用全局内存和设备内存这两个术语。为了在设备上执行内核&#xff0c;…

通过聚道云软件连接器实现钉钉与自研主数据系统的完美融合

客户介绍 某知名高校&#xff0c;拥有数千名教职工&#xff0c;日常管理涉及大量的人员异动信息。该高校设有多个学院和研究所&#xff0c;涵盖了工、理、管、文等多个学科领域。该高校是一所充满活力和潜力的学府&#xff0c;致力于为学生提供优质的教育资源和多元化的学习环…

广义零样本学习综述的笔记

1 Title A Review of Generalized Zero-Shot Learning Methods&#xff08;Farhad Pourpanah; Moloud Abdar; Yuxuan Luo; Xinlei Zhou; Ran Wang; Chee Peng Lim&#xff09;【IEEE Transactions on Pattern Analysis and Machine Intelligence 2022】 2 conclusion Generali…

三种主流流协议的浏览器播放解决方案

三种主流流协议的浏览器播放解决方案 流协议介绍 主流的流协议&#xff08;streaming protocol&#xff09;包括HLS、RTMP、RTSP&#xff0c;下面依次介绍下三种视频流。 HLS HLS&#xff08;Http Live Streaming) 是一个由苹果公司提出的基于HTTP的流媒体网络传输协议&…

微信小程序 引导地址授权 获取位置信息 uniapp

概述 获取位置信息&#xff0c;需要保证是否授权位置信息&#xff0c;有几个条件是导致无法授权的原因 &#xff08;1&#xff09;微信应用未授权定位设置 &#xff08;2&#xff09;首次进入小程序未授权位置信息 &#xff08;3&#xff09;小程序之前阻止过授权位置信息 &…

SpringBoot整合JUNIT5单元测试+Mockito

目录 第一章、快速了解JUnit单元测试1.1&#xff09;单元测试是什么1.2&#xff09;为什么使用JUnit单元测试 第二章、快速使用JUnit5框架2.1&#xff09;在pom文件中导入依赖2.2&#xff09;新建测试类2.3&#xff09;新建一个简单的测试方法 第三章、测试框架提供的注解和方法…

【设计模式】备忘录模式

一起学习设计模式 目录 前言 一、概述 二、结构 三、案例实现 1、 “白箱”备忘录模式 2、“黑箱”备忘录模式 四、优缺点 五、使用场景 总结 前言 【设计模式】备忘录模式——行为型模式。 一、概述 备忘录模式提供了一种状态恢复的实现机制&#xff0c;使得用户可以…

Android studio BottomNavigationView 应用设计

一、新建Bottom Navigation Activity项目: 二、修改bottom_nav_menu.xml: <itemandroid:id="@+id/navigation_beijing"android:icon="@drawable/ic_beijing_24dp"android:title="@string/title_beijing" /><itemandroid:id="@+i…

小游戏实战丨基于PyGame的消消乐小游戏

文章目录 写在前面PyGame消消乐注意事项系列文章写在后面 写在前面 本期内容&#xff1a;基于pygame实现喜羊羊与灰太狼版消消乐小游戏 下载地址&#xff1a;https://download.csdn.net/download/m0_68111267/88700193 实验环境 python3.11及以上pycharmpygame 安装pygame…