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

相关文章

Spring事务中@Transactional注解不生效的原因分析与解决

《Spring事务中@Transactional注解不生效的原因分析与解决》在Spring框架中,@Transactional注解是管理数据库事务的核心方式,本文将深入分析事务自调用的底层原理,解释为... 目录1. 引言2. 事务自调用问题重现2.1 示例代码2.2 问题现象3. 为什么事务自调用会失效3

mysql出现ERROR 2003 (HY000): Can‘t connect to MySQL server on ‘localhost‘ (10061)的解决方法

《mysql出现ERROR2003(HY000):Can‘tconnecttoMySQLserveron‘localhost‘(10061)的解决方法》本文主要介绍了mysql出现... 目录前言:第一步:第二步:第三步:总结:前言:当你想通过命令窗口想打开mysql时候发现提http://www.cpp

MySQL大表数据的分区与分库分表的实现

《MySQL大表数据的分区与分库分表的实现》数据库的分区和分库分表是两种常用的技术方案,本文主要介绍了MySQL大表数据的分区与分库分表的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有... 目录1. mysql大表数据的分区1.1 什么是分区?1.2 分区的类型1.3 分区的优点1.4 分

MySQL错误代码2058和2059的解决办法

《MySQL错误代码2058和2059的解决办法》:本文主要介绍MySQL错误代码2058和2059的解决办法,2058和2059的错误码核心都是你用的客户端工具和mysql版本的密码插件不匹配,... 目录1. 前置理解2.报错现象3.解决办法(敲重点!!!)1. php前置理解2058和2059的错误

Mysql删除几亿条数据表中的部分数据的方法实现

《Mysql删除几亿条数据表中的部分数据的方法实现》在MySQL中删除一个大表中的数据时,需要特别注意操作的性能和对系统的影响,本文主要介绍了Mysql删除几亿条数据表中的部分数据的方法实现,具有一定... 目录1、需求2、方案1. 使用 DELETE 语句分批删除2. 使用 INPLACE ALTER T

MySQL INSERT语句实现当记录不存在时插入的几种方法

《MySQLINSERT语句实现当记录不存在时插入的几种方法》MySQL的INSERT语句是用于向数据库表中插入新记录的关键命令,下面:本文主要介绍MySQLINSERT语句实现当记录不存在时... 目录使用 INSERT IGNORE使用 ON DUPLICATE KEY UPDATE使用 REPLACE

MySQL Workbench 安装教程(保姆级)

《MySQLWorkbench安装教程(保姆级)》MySQLWorkbench是一款强大的数据库设计和管理工具,本文主要介绍了MySQLWorkbench安装教程,文中通过图文介绍的非常详细,对大... 目录前言:详细步骤:一、检查安装的数据库版本二、在官网下载对应的mysql Workbench版本,要是

mysql数据库重置表主键id的实现

《mysql数据库重置表主键id的实现》在我们的开发过程中,难免在做测试的时候会生成一些杂乱无章的SQL主键数据,本文主要介绍了mysql数据库重置表主键id的实现,具有一定的参考价值,感兴趣的可以了... 目录关键语法演示案例在我们的开发过程中,难免在做测试的时候会生成一些杂乱无章的SQL主键数据,当我们

新特性抢先看! Ubuntu 25.04 Beta 发布:Linux 6.14 内核

《新特性抢先看!Ubuntu25.04Beta发布:Linux6.14内核》Canonical公司近日发布了Ubuntu25.04Beta版,这一版本被赋予了一个活泼的代号——“Plu... Canonical 昨日(3 月 27 日)放出了 Beta 版 Ubuntu 25.04 系统镜像,代号“Pluc

SpringBoot启动报错的11个高频问题排查与解决终极指南

《SpringBoot启动报错的11个高频问题排查与解决终极指南》这篇文章主要为大家详细介绍了SpringBoot启动报错的11个高频问题的排查与解决,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一... 目录1. 依赖冲突:NoSuchMethodError 的终极解法2. Bean注入失败:No qu