分布式事务基础

本贴最后更新于 452 天前,其中的信息可能已经时移俗易

CoverImage.jpeg

1.事务的基本概念

事务一般指的是逻辑上的一组操作,或者作为单个逻辑单元执行的一系列操作。同属于一个事务的操作会作为一个整体提交给系统,这些操作要么全部执行成功,要么全部执行失败。

2.事务的特性

总体来说,事务存在四大特性,分别是:

- 原子性(Atomic)

- 一致性(Consistency)

- 隔离性(Isolation)

- 持久性(Durability)

如下图所示,事务的四大特性又被称为:ACID

1.png

2.1 原子性

事务的原子性指的是构成事务的所有操作要么全部执行成功,要么全部执行失败,不可能出现部分执行成功,部分执行失败的情况。

例如,在转账业务中,张三向李四转账 100 元,于是张三的账户余额减少 100 元,李四的账户余额增加 100 元。在开启事务的情况下,这两个操作要么全部执行成功,要么全部执行失败,不可能出现只将张三的账户余额减少 100 元的操作,也不可能出现只将李四的账户余额增加 100 元的操作

2.2 一致性

事务的一致性指的是在事务执行之前和执行之后,数据始终处于一致的状态

例如,同样是转账业务,张三向李四转账 100 元,且转账前和转账后的数据是正确的,那么,转账后张三的账户余额会减少 100 元,李四的账户余额会增加 100 元,这就是数据处于一致的状态。如果张三的账户余额减少了 100 元,而李四的账户余额没有增加 100 元,这就是数据处于不一致状态

2.3 隔离性

事务的隔离性指的是并发执行的两个事务之间互不干扰。也就是说,一个事务在执行过程中不能看到其他事务运行过程的中间状态

例如,在张三向李四转账的业务场景中,存在两个并发执行的事务 A 和事务 B,事务 A 执行扣减张三账户余额的操作和增加李四账户余额的操作,事务 B 执行查询张三账户余额的操作。在事务 A 完成之前,事务 B 读取的张三的账户余额仍然为扣减之前的账户余额,不会读取到扣减后的账户余额

注意:MySQL 通过锁和 MVCC 机制来保证事务的隔离性

2.4 持久性

事务的持久性指的是事务提交完成后,此事务对数据的更改操作会被持久化到数据库中,并且不会被回滚

例如,在张三向李四转账的业务场景中,在同一事务中执行扣减张三账户余额和增加李四账户余额的操作,事务提交完成后,这种对数据的修改操作就会被持久化到数据库中,且不会被回滚

注意:数据库的事务在实现时,会将一次事务中包含的所有操作全部封装成一个不可分割的执行单元,这个单元中的所有操作,要么全部执行成功,要么全部执行失败。只要其中任意一个操作执行失败,整个事务就会执行回滚操作

3.事务的类型

事务主要分为五大类,分别为:

- 扁平事务

- 带有保存点的扁平事务

- 链式事务

- 嵌套事务

- 分布式事务

3.1 扁平事务

扁平事务:是事务操作中最常见,也是最简单的事务。在数据库中,扁平事务通常由 begin 或者 starttransaction 字段开始,由 commit 或者 rollback 字段结束。在这之间的所有操作要么全部执行成功,要么全部执行失败(回滚)。当今主流的数据库都支持扁平事务。

扁平事务虽然是最常见、最简单的事务,但是无法提交或者回滚整个事务中的部分事务,只能把整个事务全部提交或者回滚。为了解决这个问题,带有保存点的扁平事务出现了

3.2 带有保存点的扁平事务

通俗地讲,内部设置了保存点的扁平事务,就是带有保存点的扁平事务。带有保存点的扁平事务通过在事务内部的某个位置设置保存点(savepoint),达到将当前事务回滚到此位置的目的

示例如下:

在 MySQL 数据库中,通过如下命令设置事务的保存点:

savepoint [savepoint_name]

例如,设置一个名称为 save_user_point 的保存点,代码如下所示:

savepoint save_user_point

通过如下命令将当前事务回滚到定义的保存点位置:

rollback to [savepoint_name]

例如,将当前事务回滚到定义的名称为 save_user_point 的保存点位置,代码如下所示:

rollback to save_user_point

通过如下命令删除保存点:

release savepoint save_user_point

从本质上讲,普通的扁平事务也是有保存点的,只是普通的扁平事务只有一个隐式的保存点,并且这个隐式的保存点会在事务启动的时候,自动设置为当前事务的开始位置。也就是说,普通的扁平事务具有保存点,而且默认是事务的开始位置

3.3 链式事务

链式事务:是在带有保存点的扁平事务的基础上,自动将当前事务的上下文隐式地传递给下一个事务。也就是说,一个事务的提交操作和下一个事务的开始操作具备原子性,上一个事务的处理结果对下一个事务是可见的,事务与事务之间就像链条一样传递下去

注意:链式事务在提交的时候,会释放要提交的事务中的所有锁和保存点,也就是说,链式事务的回滚操作只能回滚到当前所在事务的保存点,而不能回滚到已提交事务的保存点

3.4 嵌套事务

嵌套事务就是有多个事务处于嵌套状态,共同完成一项任务的处理,整个任务具备原子性。嵌套事务最外层有一个顶层事务,这个顶层事务控制着所有的内部子事务,内部子事务提交完成后,整体事务并不会提交,只有最外层的顶层事务提交完成后,整体事务才算提交完成

关于嵌套事务需要注意以下几点:

1)回滚嵌套事务内部的子事务时,会将事务回滚到外部顶层事务的开始位置

2)嵌套事务的提交是从内部的子事务向外依次进行的,直到最外层的顶层事务提交完成

3)回滚嵌套事务最外层的顶层事务时,会回滚嵌套事务包含的所有事务,包括已提交的内部子事务

在主流的关系型数据库中,MySQL 不支持原生的嵌套事务,而 SQL Server 支持。不建议使用嵌套事务

3.5 分布式事务

分布式事务指的是事务的参与者、事务所在的服务器、涉及的资源服务器以及事务管理器等分别位于不同分布式系统的不同服务或数据库节点上。简单来说,分布式事务就是一个在不同环境(比如不同的数据库、不同的服务器)下运行的整体事务。这个整体事务包含一个或者多个分支事务,并且整体事务中的所有分支事务要么全部提交成功,要么全部提交失败

例如,在电商系统的下单减库存业务中,订单业务所在的数据库为事务 A 的节点,库存业务所在的数据库为事务 B 的节点。事务 A 和事务 B 组成了一个具备 ACID 特性的分布式事务,要么全部提交成功,要么全部提交失败

4. 本地事务

4.1 基本概念

在常见的计算机系统和应用系统中,很多事务是通过关系型数据库进行控制的。这种控制事务的方式是利用数据库本身的事务特性来实现,而在这种实现方式中,数据库和应用通常会被放在同一台服务器中,因此,这种基于关系型数据库的事务也可以称作本地事务或者传统事务

本地事务使用常见的执行模式,可以使用如下伪代码来表示:

transaction begin
insert into 表名 (字段名列表) values (值列表)
update 表名 set 字段名 = 字段值 where id = id
delete from 表名 where id = id
transaction commit/rollback

另外,本地事务也具有一些特征。以下列举几个本地事务具有的典型特征:

1)一次事务过程中只能连接一个支持事务的数据库,这里的数据库一般指的是关系型数据库

2)事务的执行结果必须满足 ACID 特性

3)事务的执行过程会用到数据库本身的锁机制

4.2 本地事务的执行流程

本地事务执行流程如下图所示:

2.png

从图中可以看出:

1)客户端开始事务操作之前,需要开启一个连接会话

2)开始会话后,客户端发起开启事务的指令

3)事务开启后,客户端发送各种 SQL 语句处理数据

4)正常情况下,客户端会发起提交事务的指令,如果发生异常情况,客户端会发起回滚事务的指令

5)上述流程完成后,关闭会话

本地事务是由资源管理器在本地进行管理的

4.3 本地事务的优缺点

本地事务的优点总结如下:

1)支持严格的 ACID 特性,这也是本地事务得以实现的基础

2)事务可靠,一般不会出现异常情况

3)本地事务的执行效率比较高

4)事务的状态可以只在数据库中进行维护,上层的应用不必理会事务的具体状态

5)应用的编程模型比较简单,不会涉及复杂的网络通信

本地事务的缺点总结如下:

1)不具备分布式事务的处理能力

2)一次事务过程中只能连接一个支持事务的数据库,即不能用于多个事务性数据库

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • 笔记

    好记性不如烂笔头。

    304 引用 • 777 回帖 • 1 关注
  • 阿里云

    阿里云是阿里巴巴集团旗下公司,是全球领先的云计算及人工智能科技公司。提供云服务器、云数据库、云安全等云计算服务,以及大数据、人工智能服务、精准定制基于场景的行业解决方案。

    89 引用 • 345 回帖
  • IDEA

    IDEA 全称 IntelliJ IDEA,是一款 Java 语言开发的集成环境,在业界被公认为最好的 Java 开发工具之一。IDEA 是 JetBrains 公司的产品,这家公司总部位于捷克共和国的首都布拉格,开发人员以严谨著称的东欧程序员为主。

    180 引用 • 400 回帖
  • Tomcat

    Tomcat 最早是由 Sun Microsystems 开发的一个 Servlet 容器,在 1999 年被捐献给 ASF(Apache Software Foundation),隶属于 Jakarta 项目,现在已经独立为一个顶级项目。Tomcat 主要实现了 JavaEE 中的 Servlet、JSP 规范,同时也提供 HTTP 服务,是市场上非常流行的 Java Web 容器。

    162 引用 • 529 回帖 • 3 关注
  • Hexo

    Hexo 是一款快速、简洁且高效的博客框架,使用 Node.js 编写。

    21 引用 • 140 回帖 • 28 关注
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3168 引用 • 8207 回帖
  • 创业

    你比 99% 的人都优秀么?

    82 引用 • 1398 回帖 • 1 关注
  • 生活

    生活是指人类生存过程中的各项活动的总和,范畴较广,一般指为幸福的意义而存在。生活实际上是对人生的一种诠释。生活包括人类在社会中与自己息息相关的日常活动和心理影射。

    228 引用 • 1450 回帖
  • 大疆创新

    深圳市大疆创新科技有限公司(DJI-Innovations,简称 DJI),成立于 2006 年,是全球领先的无人飞行器控制系统及无人机解决方案的研发和生产商,客户遍布全球 100 多个国家。通过持续的创新,大疆致力于为无人机工业、行业用户以及专业航拍应用提供性能最强、体验最佳的革命性智能飞控产品和解决方案。

    2 引用 • 14 回帖 • 3 关注
  • NGINX

    NGINX 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 NGINX 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。

    311 引用 • 546 回帖 • 33 关注
  • Eclipse

    Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。

    75 引用 • 258 回帖 • 626 关注
  • 以太坊

    以太坊(Ethereum)并不是一个机构,而是一款能够在区块链上实现智能合约、开源的底层系统。以太坊是一个平台和一种编程语言 Solidity,使开发人员能够建立和发布下一代去中心化应用。 以太坊可以用来编程、分散、担保和交易任何事物:投票、域名、金融交易所、众筹、公司管理、合同和知识产权等等。

    34 引用 • 367 回帖 • 1 关注
  • OkHttp

    OkHttp 是一款 HTTP & HTTP/2 客户端库,专为 Android 和 Java 应用打造。

    16 引用 • 6 回帖 • 54 关注
  • TGIF

    Thank God It's Friday! 感谢老天,总算到星期五啦!

    284 引用 • 4481 回帖 • 654 关注
  • Love2D

    Love2D 是一个开源的, 跨平台的 2D 游戏引擎。使用纯 Lua 脚本来进行游戏开发。目前支持的平台有 Windows, Mac OS X, Linux, Android 和 iOS。

    14 引用 • 53 回帖 • 513 关注
  • Sphinx

    Sphinx 是一个基于 SQL 的全文检索引擎,可以结合 MySQL、PostgreSQL 做全文搜索,它可以提供比数据库本身更专业的搜索功能,使得应用程序更容易实现专业化的全文检索。

    1 引用 • 181 关注
  • RIP

    愿逝者安息!

    8 引用 • 92 回帖 • 291 关注
  • Spark

    Spark 是 UC Berkeley AMP lab 所开源的类 Hadoop MapReduce 的通用并行框架。Spark 拥有 Hadoop MapReduce 所具有的优点;但不同于 MapReduce 的是 Job 中间输出结果可以保存在内存中,从而不再需要读写 HDFS,因此 Spark 能更好地适用于数据挖掘与机器学习等需要迭代的 MapReduce 的算法。

    74 引用 • 46 回帖 • 549 关注
  • Linux

    Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POSIX 和 Unix 的多用户、多任务、支持多线程和多 CPU 的操作系统。它能运行主要的 Unix 工具软件、应用程序和网络协议,并支持 32 位和 64 位硬件。Linux 继承了 Unix 以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。

    915 引用 • 931 回帖
  • 30Seconds

    📙 前端知识精选集,包含 HTML、CSS、JavaScript、React、Node、安全等方面,每天仅需 30 秒。

    • 精选常见面试题,帮助您准备下一次面试
    • 精选常见交互,帮助您拥有简洁酷炫的站点
    • 精选有用的 React 片段,帮助你获取最佳实践
    • 精选常见代码集,帮助您提高打码效率
    • 整理前端界的最新资讯,邀您一同探索新世界
    488 引用 • 383 回帖 • 5 关注
  • 正则表达式

    正则表达式(Regular Expression)使用单个字符串来描述、匹配一系列遵循某个句法规则的字符串。

    31 引用 • 94 回帖
  • Flutter

    Flutter 是谷歌的移动 UI 框架,可以快速在 iOS 和 Android 上构建高质量的原生用户界面。 Flutter 可以与现有的代码一起工作,它正在被越来越多的开发者和组织使用,并且 Flutter 是完全免费、开源的。

    39 引用 • 92 回帖 • 7 关注
  • 区块链

    区块链是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。所谓共识机制是区块链系统中实现不同节点之间建立信任、获取权益的数学算法 。

    91 引用 • 751 回帖 • 1 关注
  • API

    应用程序编程接口(Application Programming Interface)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。

    76 引用 • 421 回帖
  • 锤子科技

    锤子科技(Smartisan)成立于 2012 年 5 月,是一家制造移动互联网终端设备的公司,公司的使命是用完美主义的工匠精神,打造用户体验一流的数码消费类产品(智能手机为主),改善人们的生活质量。

    4 引用 • 31 回帖 • 10 关注
  • VirtualBox

    VirtualBox 是一款开源虚拟机软件,最早由德国 Innotek 公司开发,由 Sun Microsystems 公司出品的软件,使用 Qt 编写,在 Sun 被 Oracle 收购后正式更名成 Oracle VM VirtualBox。

    10 引用 • 2 回帖 • 5 关注
  • GitLab

    GitLab 是利用 Ruby 一个开源的版本管理系统,实现一个自托管的 Git 项目仓库,可通过 Web 界面操作公开或私有项目。

    46 引用 • 72 回帖 • 1 关注