当前位置: 首页 > news >正文

[Java微服务架构]7-1_事务处理——事务特性与本地事务

欢迎来到啾啾的博客🐱。
这是一个致力于构建完善的Java程序员知识体系的博客📚,记录学习的点滴,分享工作的思考、实用的技巧,偶尔也分享一些杂谈💬。
欢迎评论交流,感谢您的阅读😄。

这篇比我想的要长,分几篇发。
本篇先介绍“事务特性”与“单服务单数据源”
全盘将介绍如引言所述分布式系统中事务的处理。

下篇为[Java微服务架构]7-2_事务处理——全局事务与共享事务

引言

事务在每一个信息系统中都会涉及,数据库、分布式共享数据,只要是与信息、与数据相关的,都会涉及到事务。

Q:可我们要怎么表述事务呢?

事务是:“通过ACID特性确保数据安全与一致性的数据操作的逻辑单元”

现在需要保证数据一致性的场景很多,包括但不限于数据库、事务内存、缓存、消息队列、分布式存储等等……
事务要怎么保证这些场景的数据一致性呢?
这个问题可以拆分为以下问题,即:
”单服务单数据源“事务是怎么处理?
”单服务多数据源“事务是怎么处理呢?
”多服务单数据源“事务是怎么处理呢?
”多服务多数据源“事务(分布式事务)是怎么处理呢?

1.事务特性

ACID

原子性Atomicity 一致性Consistency 隔离性Isolation 持久性Durability。
一般来说,其中原子性 A、隔离性I、持久性D都是为了保证数据的一致性 C。即满足A、I、D,以实现数据的一致性I。

A、I、D for I

具体关于四个特性的描述,在MySQL事务开篇有提及,这里不再赘述。

内部一致性(Internal Consistency)

内部一致性指的是在分布式系统中的一个事务执行过程中,系统内部的数据状态保持逻辑上的正确性和完整性。

即,事务要么成功,要么失败。关注事务本身。

分布式系统中,内部一致性通常通过事务管理器、两阶段提交(2PC)或者日志回滚等机制来实现。

外部一致性(External Consistency)

当一个服务使用到多个不同的数据源,甚至多个不同服务同时涉及多个不同的数据源时,问题就变得困难了许多。此时,并发执行甚至是先后执行的多个事务,在时间线上的顺序并不由任何一个数据源来决定,这种涉及多个数据源的事务间一致性被称为“外部一致性”。

即,多个数据源在外部看来的一致性。全局视角。

外部一致性通常比内部一致性更难实现,因为它需要协调多个节点之间的数据同步,可能涉及 Paxos、Raft 这样的共识算法,或者使用强一致性协议。

2.本地事务(Local Transaction)

本地事务是适用于单个服务使用的单数据源场景的事务解决方案。

ARIES理论

ARIES是现代数据库的基础理论。
(Algorithms for Recovery and Isolation Exploiting Semantic,ARIES),直接翻译过来是“基于语义的恢复与隔离算法”。
其着重解决了原子性A和持久性D在算法层面上的实现。

还是算法,所以说程序就是=数据结构+算法

实现原子性和持久性

原子性和持久性在事务里是密切相关的两个属性:原子性保证了事务的多个操作要么都生效要么都不生效,不会存在中间状态;持久性保证了一旦事务生效,就不会再因为任何原因而导致其修改的内容被撤销或丢失。

实现原子性和持久性需要将数据“写入磁盘”,最大困难是“写入磁盘”这个操作并不是原子
的,不仅有“写入”与“未写入”状态,还客观存在着“正在写”的中间状态。

为了避免“未提交事务,写入后崩溃(事务未完成,部分数据写入磁盘)”、“已提交事务,写入前崩溃(事务已完成,未写入磁盘)”,需要进行数据恢复操作,即“恢复崩溃”。
有一种能“恢复崩溃”的事务实现方式为——“提交日志 (Commit Logging)”。

提交日志 Commit Logging

提交日志的核心思想是:在事务真正修改数据之前,先把事务的所有操作记录到一个持久化的日志中。这个日志通常存储在磁盘上(或高可用存储中),确保即使系统崩溃,事务的状态也能通过日志恢复。
主要作用是:

  1. 保证原子性:通过记录操作意图,确保事务要么全部完成,要么全部回滚。
  2. 提供持久性:一旦日志被写入并标记为“已提交”,即使系统故障,数据也能恢复。
  3. 支持一致性:日志记录了事务的完整状态,便于协调多个节点。
    工作流程 :
  • 1.日志记录阶段:
    • 事务开始时,系统将事务的所有操作(如“更新 A=100”“插入 B=200”)写入日志。
    • 这些操作以“意图”(intent)的形式记录,而不是直接修改数据库。
  • 2.提交阶段:
    • 当事务的所有操作都记录到日志后,系统写入一个“提交记录”(commit record),表示事务已成功。
    • 提交记录写入后,事务被认为“持久化”,即使后续崩溃也能恢复。
  • 3.应用阶段:
    • 日志提交后,系统根据日志内容实际更新数据库(称为“重做”,redo)。
  • 4.恢复阶段(如果崩溃):
    • 系统重启后,读取日志:
      • 如果有提交记录,就重做操作。
      • 如果没有提交记录,就回滚(撤销未完成的操作,称为“undo”)。

以MySQL为例简单描述,其InnoDB使用一种叫WAL (Write-Ahead Logging,预写日志)的方式提交日志:
1.执行修改数据操作,先生成Undo Log记录数据修改前状态
2.将“更改记录”写入Redo Log
3.按事务顺序将DDL和DML操作记录到Binlog
4.事务打上commit标签,正式结束。

可以看出,核心是Redo Log与Undo Log,提交日志流程借助这两者进行数据崩溃恢复。
MySQL实际数据写入流程没这么简单,这里只是提取了提交日志部分。

实现隔离性

提起隔离,很容易想到使用锁的方式进行并发隔离。
以数据库为例,有3种锁——写锁、读锁、范围锁,其中写锁排他,读锁共享,范围锁是典型的加范围(范围内不能写入)。
也可以按照范围划分为行锁、表锁、间隙锁(Gap Lock)与Next-Key Lock.

还是以MySQL为例,8.0版本默认隔离级别为RR,可重复读。
实现机制中锁为:读取加共享锁(部分情况),写操作加排他锁,范围操作可能使用 Next-Key Lock(InnoDB 默认使用 Next-Key Lock,它是行锁和间隙锁的组合)。还有MVCC。

对于隔离性来说,隔离级别越高,隔离程度越高,并发能力越低,但脏读、幻读、不可重复度现象越少。

具体隔离级别与MVCC可以看这篇MySQL事务。

http://www.dtcms.com/a/99334.html

相关文章:

  • 【商城实战(101)】电商未来已来:新技术引领商城发展新航向
  • 查看显卡算力
  • 使用LangChain Agents构建Gradio及Gradio Tools(1)——LangChain Agent概念
  • RCE--解法
  • 基于SpringBoot的“医疗设备管理系统”的设计与实现(源码+数据库+文档+PPT)
  • MySQL源码学习系列(一)-- 环境准备及常用命令
  • 【LeetCode】—169.多数元素
  • Java基础-21-基本语法-封装
  • 聚合根的特性
  • CI/CD-Jenkins安装与应用
  • 【网络编程】搭建一个简单的UDP通信服务器和客户端
  • c#winform,倒鸭子字幕效果,typemonkey字幕效果,抖音瀑布流字幕效果
  • uniapp中的流式输出
  • 蓝桥杯 14 天 十五届蓝桥杯 数字诗意
  • 雨云云应用测评!内测持续进行中!
  • 深度学习中常见的专业术语汇总
  • SQL Server 可用性组自动种子设定失败问题
  • .NET开发基础知识1-10
  • 无人机宽带自组网机载电台技术详解,50KM超远图数传输系统实现详解
  • Python控制结构详解
  • 群体智能优化算法-流向算法(Flow Direction Algorithm, FDA,含Matlab源代码)
  • FALL靶机渗透实战:从信息收集到特权升级的完整链分析
  • postgresql 重置对应表序列最大值
  • 药用植物次生代谢的多层调控-文献精读123
  • 如何利用<ruby>、<rt>、<rp>标签实现中文注音或字符注释?
  • 车载以太网网络测试 -25【SOME/IP-报文格式-1】
  • AI助力高效办公:如何利用AI制作PPT提升工作效率
  • RAG模型
  • 医疗CMS高效管理:简化更新维护流程
  • Open HarmonyOS 5.0 分布式软总线子系统 (DSoftBus) 详细设计与运行分析报告