【Seata】分布式事务解决方案——理论

news2024/10/7 16:23:33

目录

  • 回顾
    • 什么是事务
    • 数据库事务的四大特性:ACID
  • 分布式事务
    • 解释
    • 面临挑战
    • 分布式事务产生场景
      • 1. 单体架构中多数据源场景
      • 2. 分布式架构场景
    • 分布式事务解决方案
      • jta + Atomikos
      • LCN模式
        • 问题
      • Alibaba的Seata解决分布式事务
        • 问题
      • 使用MQ解决分布式事务问题
        • 问题1:关于消息丢失问题(消息可靠性)
        • 问题2:事务回滚怎么处理

回顾

什么是事务

  • 事务可以看做是一次大的活动,它由不同的小活动组成,这些活动要么全部成功,要么全部失败。

数据库事务的四大特性:ACID

  • A(Atomic):原子性,构成事务的所有操作,要么都执行完成,要么全部不执行,不可能出现部分成功部分失败的情况。

  • C(Consistency):一致性,在事务执行前后,数据库的一致性约束没有被破坏。比如:张三向李四转 100 元,转账前和转账后的数据是正确状态这叫一致性,如果出现张三转出 100 元,李四账户没有增加 100 元这就出现了数 据错误,就没有达到一致性。

  • I(Isolation):隔离性,数据库中的事务一般都是并发的,隔离性是指并发的两个事务的执行互不干扰,一个事务不能看到其他事务的运行过程的中间状态。通过配置事务隔离级别可以比避免脏读、重复读问题。

  • D(Durability):持久性,事务完成之后,该事务对数据的更改会持久到数据库,且不会被回滚。

数据库事务在实现时会将一次事务的所有操作全部纳入到一个不可分割的执行单元,该执行单元的所有操作要么都成功,要么都失败,只要其中任一操作执行失败,都将导致整个事务的回滚。

分布式事务

解释

  • 分布式事务是指涉及多个独立数据库或资源的事务处理。
  • 在分布式系统中,每个数据库或资源都是独立的,它们可能位于不同的物理位置,由不同的机器或进程管理。
  • 分布式事务的目标是确保在所有参与的数据库或资源上,事务要么全部提交成功,要么全部回滚失败,以保持整个系统的一致性。

面临挑战

  • 分布式事务面临的挑战是如何在分散的环境中协调各个参与者的操作,并确保事务的原子性、一致性、隔离性和持久性。
  • 为了解决这个问题,通常使用两阶段提交(Two-Phase Commit,2PC)协议或者三阶段提交(Three-Phase Commit,3PC)协议等机制来实现分布式事务的管理。

在分布式系统中,分布式事务的设计和实现需要考虑到网络延迟、节点故障、并发访问等问题。因此,合理的分布式事务设计是提高系统稳定性和性能的关键。

分布式事务产生场景

1. 单体架构中多数据源场景

假设有一个电子商务应用,其中包含订单服务和支付服务,订单数据存储在MySQL数据库中,而支付数据存储在另一个MongoDB数据库中。在单体架构中,订单服务和支付服务分别是独立的模块,各自维护自己的数据源。

在这个场景下,多数据源场景可能导致分布式事务问题的流程如下:

  1. 用户在下订单时,订单服务会创建一个订单,并向MySQL数据库插入订单数据。

  2. 同时,订单服务需要调用支付服务来完成支付操作。支付服务会从MongoDB数据库中查询用户的支付信息,根据订单金额进行支付,并将支付结果存储到MongoDB数据库中。

  3. 在事务开始之前,订单服务和支付服务都需要获取一个数据库连接,开启一个数据库事务。

  4. 订单服务在MySQL数据库中插入订单数据,并等待支付服务完成支付。

  5. 支付服务从MongoDB数据库中获取支付信息,并进行支付操作。

  6. 如果支付操作成功,支付服务将支付结果保存到MongoDB数据库中。

  7. 如果支付操作失败,支付服务将回滚支付操作,并且回滚MongoDB数据库中的变更。

  8. 然后,支付服务将事务提交,关闭数据库连接。

  9. 订单服务等待支付服务的响应。

  10. 如果支付服务成功完成支付并提交事务,订单服务也提交事务,订单和支付数据都保存成功。

  11. 如果支付服务执行失败或超时,订单服务将回滚订单操作,并且回滚MySQL数据库中的变更。

  12. 订单服务提交失败,订单和支付数据都没有保存成功。

在这个流程中,由于订单服务和支付服务分别维护自己的数据源,它们在进行跨数据源的操作时面临分布式事务问题。如果支付服务在支付操作后发生故障,导致支付服务无法提交事务,则订单服务的订单数据已经插入到MySQL数据库中,但支付数据未能成功保存到MongoDB数据库中,这就导致了数据的不一致。

2. 分布式架构场景

  • 简单来说:跨JVM调用接口,一定会发生分布式事务问题。
  • 在RPC接口调用的过程中,A调用B服务接口之后,当A接口报错,无法回滚B接口的事务,导致最终A接口事务回滚了,B接口事务没有回滚,因此就需要解决分布式事务问题。

分布式事务解决方案

  1. 单体架构中多数据源场景可以使用jta + Atomikos。
  2. 基于RabbitMQ的形式解决,最终一致性的思想。
  3. 基于RocketMQ解决,采用事务消息。
  4. LCN:采用LCN模式,假关闭连接(目前已经被淘汰)。
  5. Alibaba的Seata背景非常强大,已经成为了主流,但是性能一般。如果你想要解决分布式事务问题,又想接口快速响应,就不要用Seata,Seata会导致接口响应变慢,就会发生超时。如果项目是追求快速响应,建议使用MQ最终一致性方案。

jta + Atomikos

JTA(Java Transaction API)和Atomikos是两个常用的工具,可以用于解决分布式事务问题。

  1. 首先,你需要在应用程序中引入JTA和Atomikos的依赖。你可以通过Maven或Gradle等构建工具来添加这些依赖。

  2. 然后,你需要在应用程序中配置Atomikos事务管理器。配置包括数据库连接池的设置以及Atomikos事务管理器的一些属性,如事务超时时间等。

  3. 在应用程序中,你可以使用JTA注解或编程式方式来标记事务。使用JTA注解可以在方法或类级别上标记事务,而编程式方式需要在代码中显式地开启、提交或回滚事务。

  4. 如果你的应用程序需要与其他应用程序或服务进行交互,你可以使用Atomikos的分布式事务协调器来确保所有的事务操作在一个统一的事务中执行。分布式事务协调器可以通过一些配置文件中的信息来管理分布式事务。

  5. 当一个分布式事务执行完成后,你可以使用Atomikos提供的API来查看事务的状态以及处理异常。你可以根据需要进行回滚、提交或恢复事务。

LCN模式

在这里插入图片描述

  1. 发起方和参与方与我们的LCN管理器全局事务协调者一直保持长连接。
  2. 发起方在调用接口之前会使用AOP生成一个全局的事务分组ID。
  3. 发起方在调用接口的时候会在请求头中传递该全局事务分组ID。
  4. 参与方会从请求头中获取该事务分组ID,当前业务执行完毕之后不会提交该事务,则会使用假关闭。
  5. 发起方调用接口完成之后,如果出现异常的情况下,会通知事务协调者回滚该事务,协调者再通知参与方回滚事务,这样两个服务都发生了事务回滚。
问题

LCN基于数据源假关闭,事务如果不提交,有可能会导致Mysql innoDB存储引擎的行锁机制,因为你事务没提交,行锁就不会释放。而且积分服务不提交事务,其它项目查询积分根本查不到你未提交的数据。

Alibaba的Seata解决分布式事务

Seata为用户提供了AT、TCC、SAGA和XA事务模式,为用户打造一站式分布式事务解决方案。其实说起来Seata和LCN差不多
在这里插入图片描述

  • 当发起方调用参与方接口,支付服务首先更新状态为已支付,那么这时undolog日志会生成前置镜像和后置镜像,前置镜像就是修改前的状态。这时调用积分服务,积分服务insert一条积分数据,undolog日志生成前置镜像和后置镜像。

  • 那么调用已完成,这时支付服务方报错了,那么通过undolog日志会进行逆向回滚,回滚到之前的状态,然后通知事务协调者,告诉积分服务也要回滚,那么积分服务的undolog日志也进行了逆向回滚,insert的逆向就是delete,这样两个服务就都回滚成功了。

  • 那么Seata与LCN最大的区别就是,在支付服务调用积分服务接口时,积分服务insert一条数据,LCN是不提交事务的,这样就导致别人无法查询到这条新insert的数据。但Seata提交了事务,所以可以查到。

问题
  • 有可能存在短暂脏读问题。
    • 解释一下脏读:一个事务没有提交的数据被另外一个事务读到,而全局事务是多个本地事务的集合,如果在全局事务下,某个本地事务提交了,如果没有全局控制,那么这个提交的事务也有可能被其他事务读到,也是一种脏写。
  • 这个问题的本质是:全局事务中的某个本地事务完成不代表全局事务也完成。
  • 比如我们支付服务调用积分服务,积分服务insert后提交事务,再相应给支付服务,这时支付服务报错了,打算回滚自己和积分服务,但这时其它的服务是可以查到积分服务刚insert的这条数据。但这时又回滚了,再查询发现刚查到的这条数据又没了

使用MQ解决分布式事务问题

在这里插入图片描述

  1. 当支付服务更新状态为已完成,然后发送消息到MQ,
  2. 积分服务获取到消息再insert一条数据
问题1:关于消息丢失问题(消息可靠性)
  1. ACK确认机制:生产者必须确保消息投递到MQ成功
    • 如果生产者投递消息失败的情况下,则通过日志记录下来,后期通过定时任务自动补偿。
  2. 服务端消息持久化,避免MQ宕机之后消息丢失
    • 生产者发送消息到MQ服务端,服务端持久化到硬盘上,再回执给生产者,告诉它消息投递成功。
  3. 重试机制:确保消费者消息消费成功(同时注意幂等性问题)
    • 如果消费者消费失败的情况下则MQ会采用间隔的形式不断重试,重试过程中需要解决幂等性问题。
问题2:事务回滚怎么处理
  • MQ自身无法回滚,只有补偿。
  • 如果支付服务方出错,这时积分服务已经insert并提交事务,那是系统的问题,积分增加就增加了,或者之后再扣除。
  • 如果你积分服务出错了,那后续补偿再把积分补上

一个原则:最终一致性

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

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

相关文章

2025年计算机毕业设计题目参考

今年最新计算机毕业设计题目参考 以下可以参考 springboot洗衣店订单管理系统 springboot美发门店管理系统 springboot课程答疑系统 springboot师生共评的作业管理系统 springboot平台的医疗病历交互系统 springboot购物推荐网站的设计与实现 springboot知识管理系统 springbo…

管道塞满钢珠,推动一端的钢珠另一端钢珠瞬间掉落,超光速了吗?

管道塞满钢珠,推动一端的钢珠另一端钢珠瞬间掉落,超光速了吗? 现实中我们感觉钢珠瞬间掉落,好像是超光速了,其实不然,那只是我们的错觉。我们日常生活中感受到的速度与光速相比实在太慢了,以至…

MoonBit 亮相港科大「 INNOTECH 创科嘉年华」,技术创新实力备受瞩目

INNOTECH创科嘉年华 6月16日, MoonBit 作为 IDEA 研究院重点项目成果受邀参与一年一度由香港科技大学(广州)主办的「INNOTECH 创科嘉年华」,作为港科大(广州)每年最重要的科创实力展示机会,本次…

qmt量化交易策略小白学习笔记第37期【qmt编程之指数数据--如何获取迅投商品市场指数行情数据】

qmt编程之获取商品市场指数数据 qmt更加详细的教程方法,会持续慢慢梳理。 也可找寻博主的历史文章,搜索关键词查看解决方案 ! 感谢关注,咨询免费开通量化回测与获取实盘权限,欢迎和博主联系! 获取迅投商…

“AUTOSAR Nvm_WriteAll()掉电无法正常更新Nvm数据” 问题分析

1、问题现象 再掉电时调用Nvm_WriteAll()函数后,再重新上电,发现下电前更新得NvmBlock数据未被正确更新到Nvm中。掉电时直接调用Nvm_WriteBlock()函数,可以正常更新指定得NvmBlock块。 2、排查 NvM_InterWriteAll()函数有被正常执行。NvM_I…

Python期末复习题库(上)

1. (单选题) Python源程序的扩展名为( A ) A. py B. c C. class D. ph 2. (单选题) 下列( A )符合可用于注释Python代码。 A. # B. */ C. // D. $ 3. (单选题)下列关于Python 语言的特点的说法中,错误的是&#xf…

【C++修行之道】C/C++内存管理

目录 一、C/C内存分布 1. 选择题: 2. 填空题: 3. sizeof 和 strlen 区别? 二、 C语言中动态内存管理方式:malloc/calloc/realloc/free 1.malloc/calloc/realloc的区别是什么? 2.这里需要free(p2)吗&#xff…

计算机图形学入门15:几何表示

1.几何概论 通过图形学建模表示现实生活中的各种物体,要解决的第一个问题就是如何定义物体形状,而这就涉及到了几何(Geometry)。如下图所示,各种各样的玻璃水杯、车子上的不同部件、水花四溅的模拟、病毒的微观结构等这些几何形状。 那么如何…

Pikachu靶场--文件包含

参考借鉴 Pikachu靶场之文件包含漏洞详解_pikachu文件包含-CSDN博客 文件包含(CTF教程,Web安全渗透入门)__bilibili File Inclusion(local) 查找废弃隐藏文件 随机选一个然后提交查询 URL中出现filenamefile2.php filename是file2.php&…

MCK主机加固在防漏扫中的关键作用

在当今这个信息化飞速发展的时代,网络安全成为了企业不可忽视的重要议题。漏洞扫描,简称漏扫,是一种旨在发现计算机系统、网络或应用程序中潜在安全漏洞的技术手段。通过自动化工具,漏扫能够识别出系统中存在的已知漏洞&#xff0…

C++项目实战:SPDK文件系统

目录 一、Blobstore设计框架二、Cache机制三、Blob FS I/O操作四、SPDK FUSE (Filesystem in Userspcae) 前言 Blob FS是spdk面向于用户态的轻量级的文件系统 SPDK通过绕过内核(kernel bypass)的方案,构筑了用户态驱动,并利用异步轮询、无锁机制等&a…

函数依赖-函数依赖、平凡函数依赖、完全与部分函数依赖、传递函数依赖

一、引言 函数依赖是关系模式中属性与属性之间存在的一种重要数据依赖 1、将关系模式R的模式结构改为 R(SNO,CNO,SN,SD,DD,GRADE) 并对属性列进行重命名 R(学生学号&#xff0c…

msvcp100.dll已加载但找不到入口点的处理方法,分析比较靠谱的msvcp100.dll解决方法

用户在日常使用中有时会遇到一个错误提示:“已加载 msvcp100.dll,但找不到入口点”。这一信息不仅引发了使用上的不便,也对软件的稳定性产生了质疑。理解并解决该问题不仅对确保计算机正常运行至关重要,也对维护软件的长期稳定性和…

油猴 脚本如何添加包含哪个网址 执行脚本

油猴 脚本如何添加包含哪个网址 执行脚本 在这里面加上就可以 // include *://blog.csdn.net/*/article/details/* // include *.blog.csdn.net/article/details/*

【随手记】贴一段matplotlib绘图的多图拼接代码

二维: import numpy as np import matplotlib.pyplot as pltpic_names ["pic1", "pic2", "pic3", "pic4", "pic5", "pic6", "pic7", "pic8", "pic9", "pic10&qu…

代理四川公司疑难商标办理商标异议复审办理

申请商标注册或者办理其他商标事宜,可以自行办理,也可以委托依法设立的商标代理机构办理。外国人或者外国企业在中国申请商标注册和办理其他商标事宜的,应当委托依法设立的商标代理机构办理,按照被代理人的委托办理商标注册申请或…

BEV 中 multi-frame fusion 多侦融合(一)

文章目录 参数设置align_dynamic_thing:为了将动态物体的点云数据从上一帧对齐到当前帧流程旋转函数平移公式filter_points_in_ego:筛选出属于特定实例的点get_intermediate_frame_info: 函数用于获取中间帧的信息,包括点云数据、传感器校准信息、自车姿态、边界框及其对应…

EasyCVR/EasyDSS无人机直播技术助力野生动物监测:开启野生动物保护新篇章

近日有新闻报道,一名挖掘机师傅在清理河道时,意外挖出一只稀有的扬子鳄,挖机师傅小心翼翼地将其放在一边,扬子鳄也顺势游回一旁的河道中。 随着人类对自然环境的不断探索和开发,野生动物及其栖息地的保护显得愈发重要。…

压测怎么做?如何自动化?盘点各大公司全链路压测方案与实践

本文综合盘点各大公司团队的全链路压测技术方案和实践路径,供大家参考。 一、什么是全链路压测? 全链路压测指的是基于实际的生产业务场景、系统环境,模拟海量的用户请求和数据对整个业务链进行压力测试,并持续调优的过程。常用…

PyMuPDF 操作手册 - 01 从PDF中提取文本

文章目录 一、打开文件二、从 PDF 中提取文本2.1 文本基础操作2.2 文本进阶操作2.2.1 从任何文档中提取文本2.2.2 如何将文本提取为 Markdown2.2.3 如何从页面中提取键值对2.2.4 如何从矩形中提取文本2.2.5 如何以自然阅读顺序提取文本2.2.6 如何从文档中提取表格内容2.2.6.1 提…