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

相关文章

MySQL 多表连接操作方法(INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN)

《MySQL多表连接操作方法(INNERJOIN、LEFTJOIN、RIGHTJOIN、FULLOUTERJOIN)》多表连接是一种将两个或多个表中的数据组合在一起的SQL操作,通过连接,... 目录一、 什么是多表连接?二、 mysql 支持的连接类型三、 多表连接的语法四、实战示例 数据准备五、连接的性

解决IDEA报错:编码GBK的不可映射字符问题

《解决IDEA报错:编码GBK的不可映射字符问题》:本文主要介绍解决IDEA报错:编码GBK的不可映射字符问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录IDEA报错:编码GBK的不可映射字符终端软件问题描述原因分析解决方案方法1:将命令改为方法2:右下jav

MySQL中的分组和多表连接详解

《MySQL中的分组和多表连接详解》:本文主要介绍MySQL中的分组和多表连接的相关操作,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录mysql中的分组和多表连接一、MySQL的分组(group javascriptby )二、多表连接(表连接会产生大量的数据垃圾)MySQL中的

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句

MyBatis模糊查询报错:ParserException: not supported.pos 问题解决

《MyBatis模糊查询报错:ParserException:notsupported.pos问题解决》本文主要介绍了MyBatis模糊查询报错:ParserException:notsuppo... 目录问题描述问题根源错误SQL解析逻辑深层原因分析三种解决方案方案一:使用CONCAT函数(推荐)方案二:

SpringBoot3.4配置校验新特性的用法详解

《SpringBoot3.4配置校验新特性的用法详解》SpringBoot3.4对配置校验支持进行了全面升级,这篇文章为大家详细介绍了一下它们的具体使用,文中的示例代码讲解详细,感兴趣的小伙伴可以参考... 目录基本用法示例定义配置类配置 application.yml注入使用嵌套对象与集合元素深度校验开发

Python位移操作和位运算的实现示例

《Python位移操作和位运算的实现示例》本文主要介绍了Python位移操作和位运算的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 位移操作1.1 左移操作 (<<)1.2 右移操作 (>>)注意事项:2. 位运算2.1

Redis 热 key 和大 key 问题小结

《Redis热key和大key问题小结》:本文主要介绍Redis热key和大key问题小结,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、什么是 Redis 热 key?热 key(Hot Key)定义: 热 key 常见表现:热 key 的风险:二、