事务的ACID特性

news2024/12/23 10:23:03

1. 絮絮叨叨

  • 重温Apache ORC时,发现ORC支持ACID
  • 想起自己之前一度不知道ACID是哪些单词的缩写,更别提面试中常提到的事物隔离级别等知识了
  • 因此,特地学习一下数据库中事务的ACID

2. ACID

2.1 What’s transaction?

  • 考虑一个真实场景,账户A向账户B转账2000元,将涉及两次数据库写操作:
    1. update账户A的记录,余额balanceA = balanceA - 2000
    2. update账户B的记录,余额balanceB = balanceB + 2000
  • 由于某些意外,转账操作结束时,有两种不被银行系统所允许的情况出现了:
    1. 账户A的余额已减少,账户B却没有增加2000元
    2. 账户B的余额已增加,账户A却没有减少2000元
  • 也就是说,转账操作中涉及的两次数据库写操作,要么都成功,要么都失败,不允许处于中间态(in-between state
  • 这两次数据库的写操作,就是一个事务(transaction)
  • 事务是一组数据库的读写操作,这组操作是一个不可分割的整体,要么全部完成,要么都不执行,以保证数据库的一致性

2.2 ACID

  • ACID是单词Atomicity(原子性)、Consistency(一致性)、Isolation(隔离性)、Durability(持久性)的首字母缩写,是数据库支持事务所必须遵守的4个特性
  • PS: 支持事务的数据库,又叫事务型数据库(transactional databse)

2.2.1 Atomicity

  • 原子性,可能是4个特性中最好理解的一个特性,可能原子操作已经深入程序员的心了吧 😜
  • 原子性,将事务中的所有操作视为一个整体,要么都成功执行,要么都不执行。
  • 在事务的执行过程中,若某个操作失败或被中断,需要回滚(roll back)已执行的操作,使数据库恢复到事务执行之前的状态
  • 原子性可以保证数据库状态的确定性,即使在数据库崩溃或断电的情况下
  • 事务的原子性,一般都是使用日志预写技术(Write Ahead Log,WAL)中的undo日志实现

2.2.2 Consistency

  • 一致性,就是事务对数据库的更改,必须与数据库约束一致
  • 一旦破坏数据库约束,会使数据库进入非法状态,事务将被中止并进行回滚操作
  • 数据库约束,一般是为了保证数据的完整性所设置
  • 例如,转账前后,余额不能为负数。账户A原本只有2000元,却想向账户B转账2400元,这样的转账事务将被中止、回滚
    是指事务操作前和操作后,数据满足完整性约束,数据库保持一致性状态。

2.2.3 Isolation

  • 多个用户同时读写同一张表,这些事务必须在一个隔离的环境中运行,以保证互不干扰或影响
  • 隔离性,并不意味着事务不能并发执行,而是要对事务进行全局排序(global order),互不影响的事务可以同时执行,而相互影响的事务需要按序执行
  • 例如,余额为2000元的账户,同时发起两笔转账交易,每笔交易金额为1000元。转账交易完成后,账户余额为0元,而非1000元

2.2.4 Durability

  • 持久性,是指事务成功执行后,对数据所做的改动会被持久化存储,即使数据库崩溃或断电
  • 例如,账户A余额为2000元,向账户B成功转账1000元后,余额变成1000元。即使银行系统崩溃,账户A余额不允许回退到2000元,或者减少至0元
  • 事务的持久性,一般都是使用日志预写技术(Write Ahead Log,WAL)中的redo日志实现

3. 事务的隔离性

3.1 并发事务,将会带来哪些影响?

3.1.1 脏读(dirty read)

  • 事务执行完成,该事务对数据库所有操作都已提交
  • 事务B读取到了事务A未提交的数据
    • 若事务A由于某些原因发生了回滚,则事务B读取到的数据是无效的
      在这里插入图片描述
    • 若事务A成功执行,则事务B读取的数据的是有效的
  • 此时,无法保证该数据是否有效,该数据被视为脏数据,对应的read操作被称为脏读

3.1.2 不可重复读(non-repeatable read)

  • 在一个事务内多次读取同一条数据,由于其他事务对该数据的更新,使得前后两次读取到的值不一致
  • 例如,事务A、事务B同时读写lucy的银行账户。事务B提交后,lucy的账户余额变成了200万,事务B前后两次查询余额得到结果时不一致的
    在这里插入图片描述
  • 余额增加,对事务A对应的真实业务场景来说可能影响不大,但是余额减少影响就大了
    • 例如,购买一套房子要求账户余额不少于100万,第一次资格审核时,lucy可以买房
    • 签合同前,再次确认买房资格时,由于lucy的老公jack偷偷取了50万,发现账户余额为50万,lucy将丧失买房资格
    • 对lucy来说,这可是晴天霹雳啊 😂
  • 这种前后两次读取同一条数据,值却不一致的现象,被称为不可重复读

3.1.2 幻读(phantom read)

  • 在一个事务内多次执行同一个查询,前后两次的查询结果却不一致,被称作幻读
  • 例如,由于事务A增加了一条余额大于100万的账户记录,导致事务B第二次查询余额大于100万的账户数量时,发现账户数从5变成了6
    • 事务B对应银行柜员,要求本月100万存款的客户至少6个
    • 第一次查询时,发现自己业绩不达标;第二次查询,简直以为自己眼睛花了,咋100万存款的客户变成了6个
    • 甚至揉了几下眼睛、还掐了自己的大腿,以确定这不是在做梦😂
      在这里插入图片描述

3.1.4 不可重复读 VS 幻读

  • 不可重复读、幻读,都是两次查询的结果不一致,但二者的侧重有所不同
  • 不可重复读是查询同一条数据时,前后两次的值有差异

    A non-repeatable read occurs, when during the course of a transaction, a row is retrieved twice and the values within the row differ between reads.

  • 幻读是执行同一个查询时,前后两次返回的结果集有差异
  • 例如,第一次查询age > 10的学生,有108条记录;第二次查询时,由于有学生转校进来,变成109条记录

    A phantom read occurs when, in the course of a transaction, two identical queries are executed, and the collection of rows returned by the second query is different from the first.

  • 至于二者的差异,stackoverflow中的一个回答非常棒:What is the difference between Non-Repeatable Read and Phantom Read? 👍

3.2 事务隔离级别

3.2.1 隔离级别的介绍

  • 并发事务引发的脏读、不可重复度、幻影读三大问题,严重性排序如下:

    脏读 > 不可重复读 > 幻读
    
  • 需要采取一定的隔离措施,来避免这些问题的出现

  • SQL标准中提出了四种隔离级别,隔离级别越高,隔离效果越好,事务的执行性能越低

    读未提交(read uncommitted) > 读已提交(read committed) > 可重复读(repeatable read) > 串行化(serializable )
    
  • 读未提交:

    • 一个事务还未提交,它对数据库所做的变更就能被其他事务读到
    • 这是最低的隔离级别,存在脏读、不可重复读、幻读的问题,不会使用该隔离级别
  • 读已提交:

    • 一个事务提交后,它对数据库所做的变更才能被其他事务读到
    • 读已提交解决了脏读的问题,有资料说:大多数的数据库默认级别就是读已提交,如Sql Server、Oracle (有待验证
  • 可重复读:

    • 若事务自身不对某条数据做更改,则在事务的整个执行过程中,即使其他事务更新了这条数据,但该事务读到的这条数据始终不变
    • 对于可重复读,最容易想到的方法是:让事务读取数据的快照(或者是临时视图),其他事务对数据的修改不会影响快照
    • 可重复读并不能解决幻读的问题,但有资料说:可重复读是Mysql InnoDB 引擎的默认隔离级别,在很大程度上还避免了幻读问题
  • 串行化:

    • 在该隔离级别下,事务顺序执行,后一个事物的执行必须等待前一个事务的执行,自然也就不存在脏读、不可重复读、幻读三大问题
    • 这是最强的隔离级别,一般需要对数据加锁,导致数据库性能变差,一般不推荐使用

  • 在并发事务下,这些隔离级别能解决()或仍然存在(X)的问题,总结如下:

    隔离级别脏读不可重复读幻读
    读未提交XXX
    读已提交XX
    可重复读X
    串行化

3.2.2 基于隔离级别,推导事务执行结果

  • 事务A和事务B都对lucy的账户余额表进行读写操作,在不同的隔离级别下,执行结果会有所差异
    在这里插入图片描述
  • 读未提交:在事务B未提交前,事务A查询到余额V1为200万
  • 读已提交:在事务B未提交前,事务A查询到余额V1为100万;事务B提交后,事务A查询到的余额V2变200万,出现了不可重复读的问题
  • 可重复读:不管事务B是否提交,事务A查询到的余额V1和V2都是100万;事务A提交后,查询到的余额为200万
  • 串行化:事务B在事务A读取余额后,发起了update操作,存在读写冲突,事务B会暂停,直到事务A已提交

4. 后记

4.1 参考链接

  • 对ACID的介绍,mongdb的这篇文章,在笔者看来是最好的:What are ACID Properties in Database Management Systems?
  • 脏读与读未提交:Dirty Reads and the Read Uncommitted Isolation Level
  • 幻读的示意图:Phantom Read Problem in SQL Server
  • MySQL知识汇总:
    • 事务隔离级别是怎么实现的?(笔者虽然不是服务器开发方向的,但觉得这些文档应该是针对面试总结的)
    • MySQL事务隔离级别和实现原理

4.2 絮絮叨叨

  • 在学习的过程中,还发现了之前经常遇到,但未深入了解的WAL技术
  • 很多数据存储系统中,都是使用到了WAL技术,后续可以深入学习一下该技术

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

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

相关文章

42.原型对象 prototype

目录 1 面向对象与面向过程 2 原型对象 prototype 3 在内置对象中添加方法 4 constructor 属性 5 实例对象原型 __proto__ 6 原型继承 7 原型链与instanceof 7.1 原型链 7.2 instanceof 8 案例-模态框 1 面向对象与面向过程 编程思想有 面向过程 与 面向…

几何-九种二次曲面类型

(一)椭圆锥面 (1)把z平方看成一个一直变大的常数,那么可以看出延z方向,是一个一直变大的椭圆。 (2)把一个x或y赋予0,显然是一个两条关于原点对称的直线。 由上即可判断…

不小心删除了文件能恢复吗 误删除文件怎么找回

电脑是我们平时工作或者生活、学习中使用频率非常高的电子设备,已经成为了我们日常生活中不可或缺的一部分。删除文件是电脑使用过程中常见的一种操作,因为电脑的储存空间是有限的,我们需要对电脑数据进行清理,避免电脑储存空间占…

视觉检测相比于人工目视检测有哪些优势

技术的发展可以给我们带来好的结果。 是其中之一。 这在现代工业生产中非常常见。 视觉检测设备可以更好地检测生产中的错误和产品质量问题,提高工业生产的效率和自动化水平,提高工业生产的准确性,加快工作进度,节约时间&#xff…

docker too many open files解决方式

1:问题描述 今天在环境上执行docker ps命令失败,如下提示 [rootcontrol02 ~]# docker ps -a lgrep nginx Cannot connect to the Docker daemon at unix:///var/run/docker.sock, Is the docker daemon running?2:查看节点docker状态 看信…

【Arduino 和 HC-12 远程无线通信模块】

【Arduino 和 HC-12 远程无线通信模块】 1. 概述2. HC-12 无线通信模块3. Arduino 和 HC-123.1 原理图3.2 示例 01 – Arduino 代码3.3 AT 命令:3.4 例子 023.5 代码说明:4. HC-12 无线通信:使用加速度计的步进电机控制4.1 原理图4.2 代码说明:1. 概述 在本Arduino教程中,…

Web 开发的一些常用基础——HTTP请求、响应、Cookies、Session

HTTP 请求 进入浏览器的开发者模式下的 Network 监听组件,访问百度 https://www.baidu.com/,输入该 URL 后回车,观察这个过程中发生了怎样的网络请求: 请求,由客户端向服务端发出,可以分为 4 部分内容&…

基于DSP+FPGA的多轴运动控制平台(一)硬件设计

2实验平台总体方案与硬件设计 2.1.1 实验平台的功能需求分析 针对便于多轴运动控制技术的研究,培养此方面技术的人才,实验平台应能 对多轴运动实现高速高精度的控制效果,同时保证系统开放性和兼容多种算法及 参数的运行。 实验过程契合实际工…

4.16--计算机网络之HTTP篇之常见面试题篇--(复习+深入)---好好沉淀,加油呀

1.HTTP 基本概念 1.HTTP 是什么? HTTP 是超文本传输协议 HTTP 是一个在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的「约定和规范」。 「HTTP 是用于从互联网服务器传输超文本到本地浏览器的协议」,这种说法正确吗…

Android -- OkHttp的简单使用和封装

OkHttp的封装 由于是封装我们可以吧OKHttp和Gson给结合起来,那么我们在gradle文件添加以下的依赖 1 2 3 compile "com.squareup.okhttp:okhttp:2.4.0" compile com.squareup.okio:okio:1.5.0 compile "com.google.code.gson:gson:2.8.0" ①Ca…

Windows Subsystem for Android (WSA) 下载:在 Windows 11 上运行 Android 应用 (April 2023)

适用于 Android™️ 的 Windows 子系统,2023 年 4 月更新 (April 2023) 请访问原文链接:https://sysin.cn/blog/wsa/,查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org Windows 11 上适用于 Android™ 的 …

在Windbg中设置断点追踪打开C++程序远程调试开关的模块

目录 1、Windbg动态调试 2、在Windbg中设置断点 2.1、在函数入口处设置断点 2.2、在函数内部某一行上设置断点 3、设置断点跟踪对打开远程调试开关接口的调用 3.1、编写演示代码 3.2、在Windbg中设置调用SetRemoteDebugOn接口的断点进行跟踪 4、最后 VC常用功能开发汇总…

这一次,吃了Redis的亏,也败给了GPT

关注【离心计划】,一起离开地球表面 背景 组内有一个系统中有一个延迟任务的需求,关于延迟任务常见的做法有时间轮、延迟MQ还有Redis Zset等方案,关于时间轮,这边小苏有一个大学时候做的demo: https://github.com/JA…

Cacti监控远程linux机器配置(被监控端)

一、被监控机安装snmp yum -y install snmp二、被监控机的配置 vi /etc/snmp/snmpd.conf做以下更改: 1、找到com2sec notConfigUser default public 改为:com2sec notConfigUser 192.168.1.1(改成监控服务器的ip) public 2、找到acce…

【hello Linux】进程概念(上)

目录 1.操作系统(OS) 2. 进程 2.1 基本概念 2.2 task_struct 内的属性字段 2.3 查看进程 2.4 查看进程的PID及PPID 2.5 杀死进程 2.6 以文件的方式查看进程 2.7 查看退出码 2.8 上下文数据 下面介绍两个较为方便的快捷键: Linux🌷…

语义分割新范式:上海 AI Lab 联合北邮、商汤提出StructToken

来源:投稿 作者:xin 编辑:学姐 Motivation 本文将当前语义分割的方法分为两类,一类是静态逐像素分类方法(static per-pixel classification),另一类为动态逐像素分类方法(dynamic p…

Ubuntu备份与恢复

Ref: create-backup-image-of-running-ubuntu Linux中我们有权访问所有系统文件,因此,最简单且直接的备份方法是将整个根目录打包: sudo su tar -cpzf /path/to/backup.tar.gz --exclude/tmp --one-file-system /其中-cpzf 表示建立压缩归档…

MQTT 持久会话与 Clean Session

1. 会话(session) 我们将从客户端向服务端发起 MQTT 连接请求开始,到连接中断直到会话过期为止的消息收发序列称之为会话。会话是服务端和客户端的一个连接,进行消息交互前必须先建立会话。 2. 会话的生命周期 MQTT v3.1.1会话…

003_螺旋矩阵

力扣54和59题 54.顺时针打印矩阵 题目: 思路:将矩阵分为若干层,首先打印最外层的元素,然后一直往里打印 对于每层,从左上方开始以顺时针的顺序遍历所有元素。假设当前层的左上角位于(top,left),右下角位于…

Axios请求(对于ajax的二次封装)——Axios取消请求、请求体编码

Axios请求(对于ajax的二次封装)——Axios取消请求、请求体编码知识回调(不懂就看这儿!)场景复现核心干货axios取消请求AbortControllerCancelToken deprecated请求体编码浏览器qs库编码数据ES6库方法node.jsQuery stri…