MySQL进阶(再论事务)——什么是事务 事务的隔离级别 结合MySQL案例详细分析

news2025/1/2 3:22:05

在这里插入图片描述

前言

MySQL最为最流行的开源数据库,其重要性不言而喻,也是大多数程序员接触的第一款数据库,深入认识和理解MySQL也比较重要。

本篇博客阐述MySQL的事务的定义和特性,原子性,一致性,隔离性,持久性;然后结合实际的案例详细分析了事务的隔离级别:序列化(SERIALIZABLE)、可重复读(REPEATABLE READ)、提交读(READ COMMITTED)、未提交读(READ UNCOMMITTED)。

本系列文章合集如下:

【合集】MySQL的入门进阶强化——从 普通人 到 超级赛亚人 的 华丽转身

在这里插入图片描述

目录

  • 前言
  • 引出
  • 一、什么是事务
  • 二、事务的特性
  • 三、事务的使用步骤
  • 五、SQL实战
    • 1、显式事务
    • 2、隐式事物
  • 六、事务的隔离级别
    • 1、理论
    • 2、查看事务的隔离级别
  • 七、READ UNCOMMITTED 未提交读
    • 1、准备测试数据
    • 2、脏读
    • 3、不可重复读
    • 4、幻读
  • 八、 READ COMMITTED 提交读
    • 1、脏读测试--解决
    • 2、不可重复度和幻读--未解决
  • 九、REPEATABLE READ 可重复读【默认】
    • 1、不可重复读测试--解决
    • 2、幻读--未解决
  • 十、SERIALIZABLE
  • 总结

引出


1.事务(TRANSACTION)是一个不可分割的逻辑单元,包含了一组数据库操作命令,并且把所有的命令作为一个整体向系统提交,要么都执行、要么都不执行;

2.隔离级别和脏读、不可重复读以及幻象读的对应关系如下:

隔离级别脏读不可重复读幻读
READ UNCOMMITTED允许允许允许
READ COMMITED不允许允许允许
REPEATABLE READ 【默认的隔离级别】不允许不允许允许
SERIALIZABLE不允许不允许不允许

3.在MySQL数据库中,默认的事务隔离级别是REPEATABLE READ 可重复读;

一、什么是事务

事务(TRANSACTION)是一个不可分割的逻辑单元,包含了一组数据库操作命令,并且把所有的命令作为一个整体向系统提交,要么都执行、要么都不执行。

二、事务的特性

事务必须具备以下四个属性,简称ACID 属性

1、原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么全部成功,要么全部失败。
比如在同一个事务中的SQL语句,要么全部执行成功,要么全部执行失败。

2、一致性(Consistency)
事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。

换一种方式理解就是:事务按照预期生效,数据的状态是预期的状态。
比如账户A和账户B两者的余额加起来总共是5000,那么不管A和B之间如何转账,转账几次,事务结束后两个账户的钱相加起来最终还是5000。

3、隔离性(Isolation)
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间,要相互隔离。
在标准SQL规范中,定义了4个事务隔离级别,不同的隔离级别对事务的处理不同,分别是:未授权读取,授权读取,可重复读取和串行化。

4、持久性(durability)
一旦事务提交,那么数据的状态就会被永久的保存到数据库中。
即使发生系统崩溃或机器宕机等故障,只要数据库能够重新启动,那么一定能够将其恢复到事务成功结束的状态。

三、事务的使用步骤

1、开始事务

BEGIN ;START TRANSACTION;

2、提交事务

COMMIT ;

3、回滚(撤销)事务

ROLLBACK ;

五、SQL实战

使用事务有两种方式,分别为显式事务隐式事务

1、显式事务

(1)创建account表,并插入测试数据

在这里插入图片描述

create table account(
    id int primary key auto_increment,
    name varchar(20) unique not null,
    balance int
);

insert into account values(null,'zs',1000);
insert into account values(null,'lisi',1);

在这里插入图片描述

commit之后数据才提交

在这里插入图片描述

事物回滚,删除一条数据进行测试

在这里插入图片描述

回滚

在这里插入图片描述

BEGIN;
delete from account where name='zs';

ROLLBACK

保存点SAVEPOINT

在事务中创建保存点,方便后续针对保存点进行回滚。一个事务中可以存在多个保存点。

在这里插入图片描述

回滚到指定位置

在这里插入图片描述

begin;
delete from account where name='zs';
savepoint first;
delete from account where name='lisi';

ROLLBACK TO first;
COMMIT

2、隐式事物

DROP TABLE account;
create table account(
    id int primary key auto_increment,
    name varchar(20) unique not null,
    balance int
);

insert into account values(null,'zs',1000);
insert into account values(null,'lisi',1);

(1)在MySQL中执行DML语句,会自动提交事物。

delete from account where name='zs';

在这里插入图片描述

(2)MySQL中有一个系统变量 autocommit, 可以查看是否开启自动提交事物。

SHOW VARIABLES LIKE 'autocommit';

(3)把系统变量autocommit 的值设置为 OFF ,则会关闭自动提交。

SET autocommit = OFF;
#或
SET autocommit = 0;

在这里插入图片描述

(4)再次执行DML语句,发现不会自动提交。

insert into account values(null,'zs',1000);

在这里插入图片描述

(5)此时必须显示的提交事物才能生效

commit;

在这里插入图片描述

六、事务的隔离级别

1、理论

MySQL 中事务的隔离级别一共分为四种,分别如下:

  • 序列化(SERIALIZABLE)
  • 可重复读(REPEATABLE READ)
  • 提交读(READ COMMITTED)
  • 未提交读(READ UNCOMMITTED)
时刻事务1事务2
T0读取商品初始库存为2
T1扣减库存,库存为1
T2读取商品库存为1
T3回滚事务,库存为2
T4扣减库存,提交事务
T5查询库存为1

在MySQL数据库中,默认的事务隔离级别是REPEATABLE READ 可重复读

2、查看事务的隔离级别

通过如下 SQL 可以查看数据库实例默认的全局隔离级别和当前 session 的隔离级别。

(1)MySQL8 之前使用如下命令查看 MySQL 隔离级别:

SELECT @@GLOBAL.tx_isolation, @@tx_isolation;

(2)MySQL8 开始,通过如下命令查看 MySQL 默认隔离级别

SELECT @@GLOBAL.transaction_isolation, @@transaction_isolation;

在这里插入图片描述

(3)通过如下命令可以修改隔离级别(建议修改当前 session 隔离级别即可,不用修改全局的隔离级别):

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

上面这条 SQL 表示将当前 session 的数据库隔离级别设置为 READ UNCOMMITTED,设置成功后,再次查询隔离级别,发现当前 session 的隔离级别已经变了。

在这里插入图片描述

注意,如果只是修改了当前 session 的隔离级别,则换一个 session 之后,隔离级别又会恢复到默认的隔离级别,所以我们测试时,修改当前 session 的隔离级别即可。

七、READ UNCOMMITTED 未提交读

该事物隔离级别会导致出现脏读、不可重复读、幻读。

1、准备测试数据

DROP TABLE account;
create table account(
    id int primary key auto_increment,
    name varchar(20) unique not null,
    balance int
);

insert into account values(null,'zs',1000);
insert into account values(null,'lisi',1);

在这里插入图片描述

2、脏读

一个事务读到另外一个事务还没有提交的数据,称之为脏读。具体操作如下

会话A

START TRANSACTION;
UPDATE account set balance = balance -1 WHERE name = 'lisi'

会话B

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT @@GLOBAL.transaction_isolation, @@transaction_isolation;

SELECT * FROM account

在这里插入图片描述

可以看到,A 窗口中的事务,虽然还未提交,但是 B 窗口中已经可以查询到数据的相关变化了。

这就是脏读问题。

3、不可重复读

不可重复读是指一个事务先后读取同一条记录,但两次读取的数据结果不同,称之为不可重复读。

在这里插入图片描述

--  会话A
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
START TRANSACTION;
SELECT * FROM account WHERE name ='lisi';
SELECT SLEEP(10);
SELECT * FROM account WHERE name ='lisi';
COMMIT;
--  会话B
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

START TRANSACTION;
UPDATE account SET balance =  balance -500 WHERE name ='lisi';
COMMIT;

lisi的账户已经发生了变化,即前后两次查看 lisi账户,结果不一致,这就是不可重复读

和脏读的区别在于,脏读是看到了其他事务未提交的数据,而不可重复读是看到了其他事务已经提交的数据

(由于当前 SQL 也是在事务中,因此有可能并不想看到其他事务已经提交的数据)。

4、幻读

是指当事务不是独立执行时发生的一种现象。

幻象读和不可重复读非常像,看名字就是产生幻觉了。

在这里插入图片描述

--  会话A
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
START TRANSACTION;
SELECT * FROM account;
SELECT SLEEP(10);
SELECT * FROM account;
COMMIT;
--  会话B
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

START TRANSACTION;
insert into account values(null,'wangwu',1);
COMMIT;

幻读

  • 幻读说的是存不存在的问题:原来不存在的,现在存在了,则是幻读
  • 不可重复读说的是变没变化的问题:原来是A,现在却变为了B,则为不可重复读

八、 READ COMMITTED 提交读

和 READ UNCOMMITTED 相比,READ COMMITTED 主要解决了脏读的问题,对于不可重复读和幻象读则未解决。

将事务的隔离级别改为 READ COMMITTED 之后,重复上面关于脏读案例的测试,发现已经不存在脏读问题了;重复上面关于不可重复读案例的测试,发现不可重复读问题依然存在。

1、脏读测试–解决

在这里插入图片描述

--  会话A
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION;
UPDATE account set balance = balance -1 WHERE name = 'lisi'
--  会话B
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
SELECT @@GLOBAL.transaction_isolation, @@transaction_isolation;

SELECT * FROM account

2、不可重复度和幻读–未解决

九、REPEATABLE READ 可重复读【默认】

和 READ COMMITTED 相比,REPEATABLE READ 进一步解决了不可重复读的问题,但是幻象读则未解决。

1、不可重复读测试–解决

在这里插入图片描述

--  会话A
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION;
SELECT * FROM account WHERE name ='lisi';
SELECT SLEEP(10);
SELECT * FROM account WHERE name ='lisi';
COMMIT;
--  会话B
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SELECT @@GLOBAL.transaction_isolation, @@transaction_isolation;

START TRANSACTION;
UPDATE account SET balance =  balance +500 WHERE name ='lisi';
COMMIT;

注意,REPEATABLE READ 也是 InnoDB 引擎的默认数据库事务隔离级别

2、幻读–未解决

十、SERIALIZABLE

SERIALIZABLE 提供了事务之间最大限度的隔离,在这种隔离级别中,事务一个接一个顺序的执行,不会发生脏读、不可重复读以及幻象读问题,最安全。

如果设置当前事务隔离级别为 SERIALIZABLE,那么此时开启其他事务时,就会阻塞,必须等当前事务提交了,其他事务才能开启成功,因此前面的脏读、不可重复读以及幻象读问题这里都不会发生。


总结

隔离级别和脏读、不可重复读以及幻象读的对应关系如下:

隔离级别脏读不可重复读幻读
READ UNCOMMITTED允许允许允许
READ COMMITED不允许允许允许
REPEATABLE READ 【默认的隔离级别】不允许不允许允许
SERIALIZABLE不允许不允许不允许

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

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

相关文章

在 Windows 用 Chrome System Settings 设置代理

在 Windows 用 Chrome System Settings 设置代理 贴心提示:在设置代理之前,请确保您已经安装了 浏览器。 🔧 设置代理的详细步骤如下: 打开 浏览器,输入 //settings/system 并回车。 在「系统和网络设置」页面中&am…

突然发现柚子租车v1.42的小程序后端代码竟然内核文件全加密了!记录我的解密过程

因客户需求,需要定制租车小程序源码,找了很多要么很贵要么功能不满足需求,为啥这么折腾?还不是因为客户给的资金有限! 翻来覆去找到了柚子租车这个小程序功能各方面都能满足需求,然后我就尝试找最新版&…

Find My眼镜|苹果Find My技术与眼镜结合,智能防丢,全球定位

近年来,得益于国家政策的大力支持和技术的不断进步,眼镜产品的发展取得了长足的进步,正朝着高质量、多元化方向迈进。在这个趋势下,眼镜的功能性、时尚性、舒适性等方面都有了明显的提升,同时为了满足不同年龄段消费者…

[黑马程序员SpringBoot2]——基础篇2

目录: 模块创建实体类快速开发(lombok)数据层标准开发(基础CRUD)开启MP运行日志分页数据层标准开发(条件查询)业务层标准开发(基础CRUD)业务层标准开发(基于MyBatisPlus构建)表现层标准开发表现层数据一致性处理(R对象…

阿里云企业邮箱基于Spring Boot快速实现发送邮件功能

邮件在项目中经常会被用到,比如用邮件发送通知。比如,通过邮件注册、认证、找回密码、系统报警通知、报表信息等。本篇文章带大家通过SpringBoot快速实现一个发送邮件的功能。 邮件协议 下面先简单了解一下常见的邮件协议。常用的电子邮件协议有SMTP、…

xxl-job项目集成实战,全自动项目集成,可以直接使用到项目中

如果你看官方文档,在研究透,至少也得几天时间,如果你直接看我的文档,快速用到项目中,也就10分钟就搞好了。 xxl-job功能确实很强大,而且使用的人比较多,既然在使用xxl-job,那肯定是…

成为CSS选择器大师,让你的网页瞬间提升品味!

🎬 江城开朗的豌豆:个人主页 🔥 个人专栏 :《 VUE 》 《 javaScript 》 📝 个人网站 :《 江城开朗的豌豆🫛 》 ⛺️ 生活的理想,就是为了理想的生活 ! 目录 ⭐ 专栏简介 📘 文章引言 一、选…

【SpringCoud】

1,启动各个服务: 2,访问以下地址: http://localhost:5001/product/purchase/1/1/1000 浏览器输出: 控制台输出: 这里随机调用的端口号使用了轮询的方式 从服务治理中心拉去一份服务实例清单,然后通过某种负载均衡的算法选择具体的实例 Product核心逻辑代码: @RestController…

新生儿黄疸:原因、科普和注意事项

引言: 新生儿黄疸是许多新生儿面临的常见情况。虽然它通常是一种暂时的现象,但对于许多父母来说,这可能引发担忧。本文将科普新生儿黄疸的原因,提供相关信息,并为父母和监护人提供注意事项,以帮助他们更好…

如何在 SwiftUI 中创建悬浮操作按钮

文章目录 前言创建悬浮操作按钮悬浮按钮出现在屏幕的最前方悬浮按钮位于屏幕的右下角使悬浮按钮呈现圆形添加阴影总结 前言 悬浮操作按钮(Floating Action Button, FAB)是一种在 Android 和 Material Design 中使用的 UI 元素。它用于触发特定屏幕的主要…

百度迁徒数据爬虫方法

百度迁徙数据是由百度公司提供的免费开放数据集,主要包含了全国范围内各大城市的每日人口流入流出情况。这些数据来源于百度地图上的用户位置信息,通过计算得到每个小时的流入流出人数,并且可以按照省级、市级等多种维度进行分析。 百度迁徙 …

Modbus转MQTT以太网网关MQT-802主要特点和典型应用

随着社会的快速发展,物联网已经潜移默化地深入工控行业的各个领域,其高效的资源整合和强大的数据采集能力,深受客户的喜爱。上海泗博为实现客户在云端平台接收处理世界万物的信息以及实现远程控制,精心打造一款全新物联网产品&…

制作翻页电子画册,手机观看更快捷

随着科技的发展,便携式翻页电子手册越来越受到人们的青睐。这种电子手册不仅方便携带,而且可以在手机上轻松观看,非常适合那些忙碌的上班族或者学生党。与传统纸质书籍相比,电子手册不仅节省了空间,而且还可以随时随地…

C51--单片机中断

51单片机是单线程模式,需要用到硬件中断。 一、中断系统 中断系统是为使CPU具有对外界紧急事件的实时处理能力而设置的。 当中央处理器CPU正在处理某件事的时候,外界发生了紧急事件请求,要求CPU暂停当前工作,转而去处理这个紧急…

LeetCode刷题---最长回文子串

方法一&#xff1a;暴力破解 class Solution {public String longestPalindrome(String s) {if(s.length()<2){return s;}//最长长度int maxLen0;//保留索引坐标String ans "";for(int i0;i<s.length()-1;i){for(int ji1;j<s.length();j){String strs.subs…

ubuntu 下的 使用anaconda 环境运行python 项目

pycharm部署django项目到云服务器的详细流程_编程网 anaconda 安装环境 ubuntu下Anaconda安装与使用教程_ubuntu 运行anaconda_fakerth的博客-CSDN博客 激活环境 conda activate web_hook_python3.9进入到项目目录 cd /home/web-hook-main查看端口是否被占用 sudo ss …

Spring Boot集成Swagger接口分类与各元素排序问题

在上一篇中我们完成使用JSR-303校验&#xff0c;以及利用Swagger2得到相关接口文档&#xff0c;这节&#xff0c;我们在原先的基础之上&#xff0c;完成Swagger中关于对各个元素之间控制前后顺序的具体配置方法。 Swagger的接口的分组 首先我们需要对Swagger中的接口也就是以…

浅谈wheel滚轮事件

<divonWheel{(ee) > {// new WheelEvent(自定义,e) 获取 e[wheelDelta],e[deltaY] 判断滚轮方向var e new WheelEvent(syntheticWheel,ee)console.log(滚动触发事件, e,ee);console.log(滚动触发事件e.wheelDelta, e[wheelDelta],e[deltaY]);console.log(滚动触发事件e.…

Spirit:继承 gh-ost 灵魂的 MySQL 在线大表变更方案

昨天看到社区发布了一个新的 MySQL 大表变更工具 Spirit。是海外支付巨头 Block 旗下的 Cash App (地位类似于支付宝) 开源的&#xff0c;作者之前也在 PingCAP 工作过。 目前市面上做大表变更的方案有两个&#xff1a; Percona 开源的 pt-online-schema-change&#xff0c;基…

WMS仓储管理系统如何保障仓库的安全性

仓库安全一直以来都是企业运营中的重要一环&#xff0c;而WMS仓储管理系统则可以为仓库安全提供有力的保障。本文将探讨WMS仓储管理系统如何在实际应用中确保仓库的安全性。 WMS管理系统是一种专门用于管理仓库和库存的软件&#xff0c;它可以帮助企业对库存进行跟踪、管理以及…