事务详解(1)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介: 你好看官,里面请!今天笔者讲的是事务。不懂或者觉得我写的有问题可以在评论区留言,我看到会及时回复。 注意:本文仅用于学习参考,不可用于商业用途,如需转载请跟我联系。


事务(1)

如果觉得写的还可以,点个赞支持一下笔者呗!你的点赞和关注会让我更快更新哦。笔者会持续更新关于Java和大数据有关的文章。目前集中精力在更新java框架的内容。


1. 概念

事务是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。

很显然,事务的概念根本就不是给人看的(是给大神看的)。我们可以简单粗暴的理解为:对数据的一次操作就是一个事务。

1.1 事务的特性

事务具备 4 个特性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability),简称:ACID

  • 原子性:事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行(有始有终);
  • 一致性:事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束(表里如一);
  • 隔离性:多个事务并发执行时,一个事务的执行不应影响其他事务的执行(井水不犯河水);
  • 持久性:已被提交的事务对数据库的修改应该永久保存在数据库中(一诺千金)。

有始有终、表里如一、不多管闲事、一诺千金。真是集众多优秀品质于一身的奇男子。

事务竟然有这么多的优良品质,这不就是国民男朋友的标准吗?各位女生遇到这样的男生可一定不要放过呀!咦?怎么说的好像这篇专栏会有女生看似的呢?

2. 脏读、幻读、不可重复读

弄清楚概念对于我们学习一个东西有着至关重要的作用。通常我们学不会一个东西,是因为没有把它的概念搞清楚。概念很重要,但是有时候概念很抽象,不太容易理解。这个时候就需要类比,拿我们熟悉的事物做类比,通过我们已有的知识来学习新的知识。

2.1 脏读

脏读就是一个事务(A)读到了另一个事务(B)未提交的数据。

普通解释:

如果一个事务(A)读到另一个事务(B)并未提交的数据,恰好事务(B)由于某些原因导致了事务回滚,那么刚刚事务(A)就相当于读到了实际并不存在的数据。很显然,这种情况是存在问题的。

接地气解释:

某天傍晚,你跟女朋友手牵着手在路上慢慢悠悠的溜达着,你侬我侬的甜蜜着。这时你突然有一个想法:吃完晚饭带她去看刚刚上映的电影。但转念一想,不行,今晚有你超级喜欢的球队比赛直播,于是你打消了看电影的想法。但是此时,女朋友愤然甩开你的手,愤愤的扬长而去,留下你一个人在风中凌乱(因为她读到了你的想法)。

试想一下,如果你的女朋友能够读到你的想法,那将是一件多么可怕的事情,分分钟引来杀身之祸。

2.2 不可重复读

不可重复读是指在一个事务内对同一条记录(可以理解为根据同一个 Id 查询)进行多次查询的结果却不一致。

普通解释:

比如在一个事务(A)中,查询了一次账户余额。这时另一个事务(B)在该账户中扣除一笔钱(比如自动还款)并提交了事务,这时事务(A)再次查询账户余额,发现余额变了,这就不可重复读了。很显然,这种情况同样是存在问题。

接地气解释:

你跟好基友在商量假期怎么安排,你说想带女朋友一起出去玩。女朋友在旁边无意中听到了,她听到后很开心。但她不放心,想再确认一下,然后又凑过来偷听,这时候,你已经被好基友说服,要一起参加一个球迷聚会。你女朋友发现跟之前说的不一样了,于是你面前出现了一块搓衣板。

2.3 幻读

幻读指的是在同一个事务内进行多次操作之间,产生了新的数据,并对后续的操作造成了影响。

单纯的文字描述幻读不太好描述清楚,下面我们直接用代码来演示一下:

事务 A

mysql> begin;
Query OK, 0 rows affected (0.00 sec)
# 查询是否存在 Id 为 2 的数据
mysql> select * from user where id = 2;
Empty set (0.00 sec)
# 发现并不存在,准备插入数据。此时,另一个事务进来“捣乱”了
# 等真正执行插入的时候,发现无法插入数据
mysql> INSERT INTO `user` VALUES (2, 'xiaoqiang', 18);
ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'
# 再次查询,仍然无法查到对应数据,真是见鬼了
mysql> select * from user where id = 2;                                       
Empty set (0.00 sec)

事务 B

# 在事务 A 执行插入 Id 为 2 的数据之前,抢先插入一条 Id 为 2 的数据
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO `user` VALUES (2, 'xiaoqiang', 18);
Query OK, 1 row affected (0.01 sec)
mysql> commit;
Query OK, 0 rows affected (0.01 sec)

看完这个例子,相信这次不用把女朋友大人请出来,你就能够清楚的理解什么是幻读了吧。

2.4 区别

脏读 指的是一个事务读到了其他事物未提交的数据

不可重复读 指的是一个事务中多次读到同一条(批)数据发生了变化,重点在于表里已经存在的数据被其他事务修改了(update/delete)。

幻读 指的是一个事务被其他事务新增的数据所影响,重点在于影响事务的数据开始是不存在的,是在事务开始后,被其他事务新插入的(insert)。

脏读、不可重复读、幻读是在并发事务的情况下才会发生的。为了解决这些问题,数据库引入了隔离级别,不同的隔离级别可以解决不同的问题。

3 隔离级别

下面是不同隔离级别与发生读问题的关系对照表:

隔离级别 脏读 不可重复读 幻读
读未提交(Read uncommitted) 可能 可能 可能
读已提交(Read committed) 不可能 可能 可能
可重复读(Repeatable read) 不可能 不可能 可能
可串行化(Serializable) 不可能 不可能 不可能

读未提交 (Read Uncommitted): 所有读问题都可能发生,一般不会使用这种隔离级别

读已提交 (Read Committed): 只能避免脏读的情况发生,Oracle 的默认隔离级别

可重复读 (Repeated Read): 能够避免脏读和不可重复读,MySQL 中 InnoDB 引擎默认的隔离级别

串行 (Serializable): 可以解决所有读问题,但由于是串行执行,性能相当一般,所有通常也不会被使用

3.1 悲观锁和乐观锁

悲观锁

锁如其名,天生悲观,对于一切都持悲观态度,极度缺乏安全感,甚至到了被迫害妄想症的地步,觉得总有刁民想害朕。所有对于一切数据库操作(增删改查)都会加锁,导致所有事务只能串行执行,虽然保证了安全,但也导致了效率极其低下。

乐观锁

与悲观锁性格迥异,天生的乐天派,认为人之初性本善。对世界保持这友好开发的态度。但它绝非是一个无脑的傻白甜,它拥有过人的智慧与洞穿一切的观察能力。一旦发现有人图谋不轨,它也绝不手软,是一个既有菩萨心肠,又有霹雳手段的高手。

由于它乐观的处事态度,它更加的信任其他人,所以在与人合作的时候少了不必要的猜疑与防范,把更多的精力用在如何把事情做好上,所以效率非常的高。再加上它超人的智慧与洞察力,也能很好的保证大家做的都是好事。

乐观锁超人的智慧与洞察力其实就是数据的版本记录机制。就是为数据增加一个版本标识,读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交数据的版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。

4. 传播行为

上面讨论的内容都是事务独立作战的场景(虽然有并发情况,但是事务之间并没有什么交集)。而事务的传播行为则是在事务之间出现包含或者叫嵌套时才会用到的。Spring 中有七种事务的传播行为,具体见下表:

事务传播行为类型 说明
PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与 PROPAGATION_REQUIRED 类似的操作。

加粗项为比较常用的选项,其他不太常用。下一节会详细展开。

5 总结

OK,在这一节中,我们学习了事务的概念,了解了事务的四个特性 —— 原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。还学习了脏读、不可重复读以及幻读,并且对比了它们的区别与侧重点。然后引出了事务的隔离级别,还有悲观锁与乐观锁。最后简单介绍了一下 Spring 中事务的传播行为。可谓是收获满满的一节,而在下一节中我们会从代码层面去进一步深入的学习事务在日常开发中的应用,我在下一节等你!

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
存储 缓存 自然语言处理
深入PHP内核:Opcode缓存与性能优化
【5月更文挑战第31天】 在提升PHP应用性能的众多策略中,Opcode缓存技术以其显著的性能提升效果而广受关注。本文旨在深入探讨PHP的Opcode缓存机制,解析其对性能提升的影响,并讨论如何通过配置和优化实践来充分利用Opcode缓存。文章将首先介绍Opcode的概念及其在PHP执行过程中的作用,然后分析几种流行的Opcode缓存解决方案,最后提供针对性的优化建议,帮助开发者实现高效的PHP应用。
|
机器学习/深度学习 存储 人工智能
知识图谱嵌入模型 (KGE) 的总结和比较
知识图谱嵌入(KGE)是一种利用监督学习来学习嵌入以及节点和边的向量表示的模型。它们将“知识”投射到一个连续的低维空间,这些低维空间向量一般只有几百个维度(用来表示知识存储的内存效率)。向量空间中,每个点代表一个概念,每个点在空间中的位置具有语义意义,类似于词嵌入。
1500 0
知识图谱嵌入模型 (KGE) 的总结和比较
|
机器学习/深度学习 算法 前端开发
「LeetCode」438-找到字符中所有字母异位词⚡️
「LeetCode」438-找到字符中所有字母异位词⚡️
151 0
「LeetCode」438-找到字符中所有字母异位词⚡️
码上公益|事实孤儿的隐形守护者
公益组织和爱心极客们用数字化技术,守护事实孤儿健康成长
500 0
码上公益|事实孤儿的隐形守护者
|
流计算 Apache SQL
Apache Flink 为什么能够成为新一代大数据计算引擎?
大数据时代对人类的数据驾驭能力提出了新的挑战,Flink 的诞生为企业用户获得更为快速、准确的计算能力提供了前所未有的空间与潜力。作为公认的新一代大数据计算引擎,Flink 究竟以何魅力成为阿里、腾讯、滴滴、美团、字节跳动、Netflix、Lyft 等国内外知名公司建设流计算平台的首选?
Apache Flink 为什么能够成为新一代大数据计算引擎?
|
新零售 测试技术 API
解决最后一公里-PTS铂金版发布数据工厂
PTS(Performance Testing Service)是web化、卓越的SaaS性能测试平台,具备强大的分布式压测能力,可模拟海量用户的真实业务场景。PTS铂金版的压力发起来源是遍布全国上百个城市和各运营商的CDN节点,相比业界产品启动更快速,来源更广泛,脉冲能力和流量掌控能力更强。
2452 0
|
9天前
|
弹性计算 关系型数据库 微服务
基于 Docker 与 Kubernetes(K3s)的微服务:阿里云生产环境扩容实践
在微服务架构中,如何实现“稳定扩容”与“成本可控”是企业面临的核心挑战。本文结合 Python FastAPI 微服务实战,详解如何基于阿里云基础设施,利用 Docker 封装服务、K3s 实现容器编排,构建生产级微服务架构。内容涵盖容器构建、集群部署、自动扩缩容、可观测性等关键环节,适配阿里云资源特性与服务生态,助力企业打造低成本、高可靠、易扩展的微服务解决方案。
1199 4
|
8天前
|
机器学习/深度学习 人工智能 前端开发
通义DeepResearch全面开源!同步分享可落地的高阶Agent构建方法论
通义研究团队开源发布通义 DeepResearch —— 首个在性能上可与 OpenAI DeepResearch 相媲美、并在多项权威基准测试中取得领先表现的全开源 Web Agent。
1148 87

热门文章

最新文章