MySQL-基础篇-事务(事务简介、事务操作、事务的四大特性、并发事务引发的问题、事务的隔离级别)

本文主要是介绍MySQL-基础篇-事务(事务简介、事务操作、事务的四大特性、并发事务引发的问题、事务的隔离级别),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 1. 事务简介
  • 2. 事务操作
    • 2.1 未控制事务
    • 2.2 控制事务
      • 2.2.1 查看事务的提交方式
      • 2.2.2 设置事务的提交方式
      • 2.2.3 提交事务
      • 2.2.4 回滚事务
      • 2.2.5 开启事务
      • 2.2.6 完善转账案例
  • 3. 事务的四大特性(ACID)
  • 4. 并发事务引发的问题
  • 5. 事务隔离级别
    • 5.1 演示
      • 5.1.1 Read Uncommitted(RU)
      • 5.1.2 Read Committed(RC)
      • 5.1.3 Repeatable Read(RR)
      • 5.1.4 Serializable
    • 5.2 查看隔离级别
    • 5.3 设置事务隔离级别
    • 5.4 面试题(为什么阿里巴巴会将 MySQL 的事务隔离级别设置为 Read Committed)

1. 事务简介

DBMS:Database Management System,数据库管理系统

事务(Transaction)是数据库管理系统(DBMS)中一个不可分割的工作单位,它由一系列操作组成,这些操作要么全部成功执行,要么全部失败回滚,不会处于中间状态

事务的主要目的是保证数据的一致性和完整性,常见的事务案例就是银行转账


我们先来看一下正常的银行转账业务

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

我们再来看一下转账异常的情况,如果张三取出钱后,再转账给李四的过程中业务出现了异常,会怎么样呢

如果业务出现了异常,张三的钱扣了,但是李四却没收到钱,出现了数据不一致的情况

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

那怎么解决呢,我们只需要把整个流程都放在一个事务里面,当所有操作都执行完成了之后,再提交事务

在这里插入图片描述

MySQL 的事务默认是自动提交的,也就是说,当执行一条 DML 语句时,MySQL 会立即隐式地提交事务

2. 事务操作

我们先准备一张名为 account 的表,表的结构和表数据如下

create table account
(id    int primary key AUTO_INCREMENT comment 'ID',name  varchar(10) comment '姓名',money double(10, 2) comment '余额'
) comment '账户表';insert into account(name, money)
VALUES ('张三', 2000),('李四', 2000);

在这里插入图片描述

2.1 未控制事务

我们先来测试正常情况

-- 1.查询张三余额
select *
from account
where name = '张三';-- 2.张三的余额减少1000
update account
set money = money - 1000
where name = '张三';-- 3.李四的余额增加1000
update account
set money = money + 1000
where name = '李四';

测试完毕之后检查数据的状态, 可以看到数据操作前后是一致的

在这里插入图片描述


测试异常情况

我们先把数据都恢复到2000, 接着一次性执行以下 SQL 语句

-- 1.查询张三余额
select *
from account
where name = '张三';-- 2.张三的余额减少1000
update account
set money = money - 1000
where name = '张三';出错了....-- 3.李四的余额增加1000
update account
set money = money + 1000
where name = '李四';

由于 出错了.... 这句话 不符合 SQL 语法,执行后会报错

检查最终的数据情况,发现数据在操作前后并不一致

在这里插入图片描述

2.2 控制事务

2.2.1 查看事务的提交方式

SELECT @@autocommit;

2.2.2 设置事务的提交方式

autocommit = 1 表示自动提交

SET @@autocommit = 0;

2.2.3 提交事务

commit;

2.2.4 回滚事务

rollback;

2.2.5 开启事务

start transaction;

2.2.6 完善转账案例

-- 开启事务
start transaction;-- 1.查询张三余额
select *
from account
where name = '张三';-- 2.张三的余额减少1000
update account
set money = money - 1000
where name = '张三';-- 3.李四的余额增加1000
update account
set money = money + 1000
where name = '李四';-- 如果正常执行完毕, 则提交事务
commit;-- 如果执行过程中报错, 则回滚事务
rollback;

3. 事务的四大特性(ACID)

  1. 原子性(Atomicity): 原子性确保事务中的所有操作要么全部完成,要么全部不完成,不会出现部分完成的情况。事务中任何一个操作失败,整个事务将被回滚,就像事务从未执行过一样
  2. 一致性(Consistency): 一致性确保事务执行的结果是数据库状态的合法状态,即数据库在事务开始和结束时的数据满足预定义的约束条件(如外键约束、唯一性约束等)
  3. 隔离性(Isolation): 隔离性确保并发执行的事务彼此隔离,一个事务的中间状态不会被其他事务所见。这意味着即使在多个事务同时执行时,每个事务都感觉自己是唯一在执行的事务
  4. 持久性(Durability): 持久性确保一旦事务提交,其结果就永久保存在数据库中。即使发生系统故障,如电源故障或系统崩溃,已提交事务的结果也不会丢失,持久性一般是通过将事务的输出写入到持久存储设备(如硬盘)来保证

4. 并发事务引发的问题

  • 赃读:一个事务读到另外一个事务还没有提交的数据
  • 不可重复读:一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读
  • 幻读:一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了"幻影"

脏读的示例(事务 A 中没提交的数据被事务 B 读取)

在这里插入图片描述

不可重复读的示例(事务 A 在第一步和第三步查询的 id 为 1 的数据不一致)

在这里插入图片描述

幻读的示例

  1. 事务 A 在第一步查询到 id 为 1 的数据不存在
  2. 事务 A 在执行 insert 语句前,事务 B 提交了事务,往表中插入了 id 为 1 的数据
  3. 事务 A 在第二步执行 insert 语句,执行失败,因为破坏了主键的唯一性
  4. 事务 A 在第三步查询到 id 为 1 的数据仍然不存在

在这里插入图片描述

5. 事务隔离级别

为了解决并发事务所引发的问题,在数据库中引入了事务隔离级别,事务隔离级别主要有以下几种:

在这里插入图片描述

5.1 演示

我们来演示一下,在不同的隔离级别情况下,并发事务可能引发的问题

5.1.1 Read Uncommitted(RU)

脏读(一个事务读到了另一个事务还没有提交的数据)

在这里插入图片描述

5.1.2 Read Committed(RC)

Read Committed 隔离级别虽然解决了脏读问题,但是没有解决不可重复读的问题(一个事务先后读取同一条记录,但两次读取的数据不同)

在这里插入图片描述

5.1.3 Repeatable Read(RR)

Read Committed 隔离级别虽然解决了不可重复读问题,但是没有解决幻读的问题(一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了"幻影")

在这里插入图片描述

在这里插入图片描述

5.1.4 Serializable

Read Committed 隔离级别解决了所有并发事务引发的问题

在这里插入图片描述

5.2 查看隔离级别

查看事务隔离级别

SELECT @@TRANSACTION_ISOLATION;

5.3 设置事务隔离级别

SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
  • SESSION 设置的是当前会话(也就是当前连接)的隔离级别
  • GLOBAL 设置的是全局隔离级别

事务隔离级别越高,数据越安全,但是性能越低

示例

SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;

5.4 面试题(为什么阿里巴巴会将 MySQL 的事务隔离级别设置为 Read Committed)

既然 MySQL 默认的事务隔离级别是 Repeatable Read,那为什么阿里巴巴会将 MySQL 的事务隔离级别设置为 Read Committed,谈谈你的理解

参考回答:

MySQL 的默认事务隔离级别是REPEATABLE READ,这是一个相对较高的隔离级别,可以防止不可重复读和脏读

阿里巴巴将 MySQL 的事务隔离级别设置为READ COMMITTED,可能是因为以下几个原因:

  1. 性能考虑READ COMMITTED是比REPEATABLE READ低的隔离级别,因此在某些情况下可能会提供更好的性能。特别是在高并发环境下,READ COMMITTED可以减少锁的持有时间,从而提高系统的响应速度和吞吐量
  2. 业务场景:对于阿里巴巴的业务场景来说,幻读可能不是一个大问题,READ COMMITTED足以满足需求,而REPEATABLE READ可能会造成一些不必要的性能开销
  3. 可控的并发问题:阿里巴巴可能有能力管理和控制其系统中的并发问题,即使使用READ COMMITTED。这意味着,阿里巴巴可能可以通过其他手段(如调整应用层逻辑、优化数据库设计和使用合适的索引等)来减少并发问题带来的影响
  4. 避免死锁:降低事务的隔离级别可以减少发生死锁的概率,特别是在频繁进行更新操作的环境中

阿里巴巴将 MySQL 的事务隔离级别设置为READ COMMITTED,可能是基于性能、并发控制、业务需求和故障处理等多方面的考虑,每个公司和组织都应该根据自己的业务场景来决定使用哪个隔离级别

这篇关于MySQL-基础篇-事务(事务简介、事务操作、事务的四大特性、并发事务引发的问题、事务的隔离级别)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1124030

相关文章

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型的操作流程

《0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeekR1模型的操作流程》DeepSeekR1模型凭借其强大的自然语言处理能力,在未来具有广阔的应用前景,有望在多个领域发... 目录0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型,3步搞定一个应

SQL 中多表查询的常见连接方式详解

《SQL中多表查询的常见连接方式详解》本文介绍SQL中多表查询的常见连接方式,包括内连接(INNERJOIN)、左连接(LEFTJOIN)、右连接(RIGHTJOIN)、全外连接(FULLOUTER... 目录一、连接类型图表(ASCII 形式)二、前置代码(创建示例表)三、连接方式代码示例1. 内连接(I

解决jupyterLab打开后出现Config option `template_path`not recognized by `ExporterCollapsibleHeadings`问题

《解决jupyterLab打开后出现Configoption`template_path`notrecognizedby`ExporterCollapsibleHeadings`问题》在Ju... 目录jupyterLab打开后出现“templandroidate_path”相关问题这是 tensorflo

如何解决Pycharm编辑内容时有光标的问题

《如何解决Pycharm编辑内容时有光标的问题》文章介绍了如何在PyCharm中配置VimEmulator插件,包括检查插件是否已安装、下载插件以及安装IdeaVim插件的步骤... 目录Pycharm编辑内容时有光标1.如果Vim Emulator前面有对勾2.www.chinasem.cn如果tools工

在MySQL执行UPDATE语句时遇到的错误1175的解决方案

《在MySQL执行UPDATE语句时遇到的错误1175的解决方案》MySQL安全更新模式(SafeUpdateMode)限制了UPDATE和DELETE操作,要求使用WHERE子句时必须基于主键或索引... mysql 中遇到的 Error Code: 1175 是由于启用了 安全更新模式(Safe Upd

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

Java多线程父线程向子线程传值问题及解决

《Java多线程父线程向子线程传值问题及解决》文章总结了5种解决父子之间数据传递困扰的解决方案,包括ThreadLocal+TaskDecorator、UserUtils、CustomTaskDeco... 目录1 背景2 ThreadLocal+TaskDecorator3 RequestContextH

关于Spring @Bean 相同加载顺序不同结果不同的问题记录

《关于Spring@Bean相同加载顺序不同结果不同的问题记录》本文主要探讨了在Spring5.1.3.RELEASE版本下,当有两个全注解类定义相同类型的Bean时,由于加载顺序不同,最终生成的... 目录问题说明测试输出1测试输出2@Bean注解的BeanDefiChina编程nition加入时机总结问题说明

关于最长递增子序列问题概述

《关于最长递增子序列问题概述》本文详细介绍了最长递增子序列问题的定义及两种优化解法:贪心+二分查找和动态规划+状态压缩,贪心+二分查找时间复杂度为O(nlogn),通过维护一个有序的“尾巴”数组来高效... 一、最长递增子序列问题概述1. 问题定义给定一个整数序列,例如 nums = [10, 9, 2

Spring AI Alibaba接入大模型时的依赖问题小结

《SpringAIAlibaba接入大模型时的依赖问题小结》文章介绍了如何在pom.xml文件中配置SpringAIAlibaba依赖,并提供了一个示例pom.xml文件,同时,建议将Maven仓... 目录(一)pom.XML文件:(二)application.yml配置文件(一)pom.xml文件:首