MySQL篇(事务 - 基础)

news2024/11/15 14:02:42

目录

一、简介

二、事务操作

1. 数据准备

2. 未控制事务

2.1. 测试正常情况

2.2. 测试异常情况

3. 控制事务

3.1. 控制事务一

查看/设置事务提交方式

提交事务

回滚事务

3.2. 控制事务二

开启事务

提交事务

回滚事务

3.3. 转账案例

四、事务的好处

五、事务四大特性(ACID)

五、事务能干什么用

六、事务控制

1. 查看事务参数状态

2. 查看事务提交模式

3. 修改事务提交模式:手动提交模式

4. 恢复自动提交模式

5. 开启事务

6. 提交事务

7. 回滚事务

8. 自动提交模式下开启事务

七、并发事务问题

1. 脏读

模板一

模板二

2. 不可重复读

模版一

模板二

3. 虚读/幻读

模板一

模板二

4. 第一类更新

5. 第二类更新

八、事务隔离级别

1. 简介

2. Oracle 支持 2 种事务隔离级别

3. MySQL支持 4 种事务隔离级别

4. 隔离级别操作

查看当前会话隔离级别

查看系统隔离级别

设置当前会话隔离级别

设置系统隔离级别

查看锁资源使用情况

查看锁等待

查看事务


一、简介

事务就是一系列sql语句的组合,是一个整体,在执行的过程中要么都一起成功,要么一起失败

在数据库中,所谓事务是指一组逻辑操作单元,使数据从一种状态变换到另一种状态。

为确保数据库中数据的一致性,数据的操纵应当是离散的成0组的逻辑单元,当它全部完成时,数据的一致性可以保持,

而当这个单元中的一部分操作失败,整个事务应全部视为错误,所有从起始点以后的操作应全部回退到开始状态。

DML 语句需要事务,DDL、DQL 可不需要事务。

简单来说:

事务 是一组操作的集合,它是一个不可分割的工作单位,

事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。

就比如:

张三给李四转账1000块钱,张三银行账户的钱减少1000,而李四银行账户的钱要增加1000。

这一组操作就必须在一个事务的范围内,要么都成功,要么都失败。

正常情况:

转账这个操作, 需要分为以下这么三步来完成 , 三步完成之后, 张三减少1000, 而李四增加1000, 转账成功 :

异常情况:

转账这个操作, 也是分为以下这么三步来完成 , 在执行第三步是报错了,

这样就导致张三减少1000块钱, 而李四的金额没变, 这样就造成了数据的不一致, 就出现问题了。

为了解决上述的问题,就需要通过数据的事务来完成,我们只需要在业务逻辑执行之前开启事务,执行完毕后

提交事务。

如果执行过程中报错,则回滚事务,把数据恢复到事务开始之前的状态。

注意:

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

二、事务操作

1. 数据准备

drop table if exists account;

-- 数据准备
create table account(
  id int auto_increment primary key comment '主键ID',
  name varchar(10) comment '姓名',
  money int comment '余额'
) comment '账户表';

insert into account(id, name, money) VALUES (null,'张三',2000),(null,'李四',2000);

2. 未控制事务

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 = '李四';

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

2.2. 测试异常情况

-- 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语句

(出错了.... 这句话不符合SQL语法,执行就会报错),

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

3. 控制事务

3.1. 控制事务一

查看/设置事务提交方式
SELECT @@autocommit;

SET @@autocommit = 0;
提交事务
COMMIT;
回滚事务
ROLLBACK;

注意:

上述的这种方式,我们是修改了事务的自动提交行为, 把默认的自动提交修改为了手动提交,

此时我们执行的DML语句都不会提交, 需要手动的执行commit进行提交。

3.2. 控制事务二

开启事务
START TRANSACTION 或 BEGIN ;
提交事务
COMMIT;
回滚事务
ROLLBACK;

3.3. 转账案例

-- 开启事务

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;

四、事务的好处

通过以上案例发现事务的好处如下:

① 保证数据一致性,修改过的数据在没有提交之前是不能被其他用户看到的;

② 在数据永久性生效前可以撤回原来的修改操作;

③ 将相关操作组织在一起,一个事务中相关的数据改变或者都成功,或者都失败。

五、事务四大特性(ACID)

  1. 原子性(atomicity)一个事务必须被视为一个不可分割的工作单元,整个事务中的所有操作要么全部提交

成功,要么全部失败回滚。对于一个事务来说,不可能只执行其中的一部分操作,这就是事务的原子性。

  1. 一致性(consistency)数据库总是从一个一致性状态转换到下一个一致性状态。在前面的例子中,一致性

确保了,即使在执行第3、4条语句之间时系统崩溃,支票账户中也不会损失200美元。如果事务最终没有

提交,该事务所做的任何修改都不会被保存到数据库中。

  1. 隔离性(isolation)通常来说,一个事务所做的修改在最终提交以前,对其他事务是不可见的,这就是隔

离性带来的结果。在前面的例子中,当执行完第3条语句、第4条语句还未开始时,此时有另外一个账户汇

总程序开始运行,其看到的支票账户的余额并没有被减去200美元。后面我们讨论隔离级别(isolation

level)的时候,会发现为什么我们要说“通常来说”是不可见的。

  1. 持久性(durability)一旦提交,事务所做的修改就会被永久保存到数据库中。此时即使系统崩溃,数据也

不会丢失。持久性是一个有点模糊的概念,实际上持久性也分很多不同的级别。有些持久性策略能够提供

非常强的安全保障,而有些则未必。而且不可能有100%的持久性保障(如果数据库本身就能做到真正的

持久性,那么备份又怎么能增加持久性呢?)。

五、事务能干什么用

事务是访问和更新数据库的程序执行单元,事务中包含一个或者多个SQL语句,这些语句要么都执行,要么就

都不执行,也就是要么都成功,要么都不成功。

介绍四大特性之前先来说下MySQL的架构:

第一层:客户端层,实现链接处理,身份验证,确保安全性等。

第二层:服务器层,大多数MySQL的核心功能都在这一层,包括查询解析、分析、优化、一级所有的内置

函数(日期,时间、数学、加密函数),以及跨存储引擎的功能(存储过程,触发器,视图等)。

第三层:存储引擎层,负责数据的存储和提取。事务的实现也是在存储引擎中实现的。

MySQL事务的提交与回滚:

- start transaction(开启事务)

- 要执行的SQL语句

- commit/rollback (提交/回滚)

MySQL默认自动提交事务,手动提交事务设置:

set autocommit = 0

上面介绍完相关的理论,记下来我们来详细介绍下到底什么是ACID。

上面介绍完相关的理论,记下来我们来详细介绍下到底什么是ACID。

原子性:

原子性是指一个事务是一个不可分割的单位,是一个最小的操作单元,事务中的操作,要么全成功,要

么全不成功。如果事物中的一个sql语句执行失败了,那么已经执行的SQL语句,要执行回滚动作,回滚到这个

事务执行之前的状态。它的实现原理,主要是通过undo log,它是一个日志,innodb存储引擎提供了两种事

务的日志,一个是redo log,还有一个undo log。原子性的体现,就是在回滚上面,如果SQL报错的话,会

执行回滚,回滚到执行之前的状态。那么怎么回到执行之前的状态呢,这就需要把执行之前的状态记录下

来,一旦这个SQL语句发生错误之后,我们就可以回到我们之前的状态,举个例子:在我们程序上线的过程

中,如果程序上线失败,或者刚上线的时候遇到一些不能及时解决的bug,这个时候我们要把当前的错误版本

回滚到上一个正确的版本,它们之间的原理是相通的,就是我需要要记住上一个正确的版本是什么,当这个事

务对数据库进行修改的时候,innodb就会生成这个对应的undo log,记录这个sql执行的相关信息,如果语句

执行失败,发生回滚,innodb就会根据这个undo log内容去做相反的工作,比如执行了一个insert的操作,

那么回滚的时候,就会执行一个相反的操作,就是delete,我之前执行的是一个delete操作呢,那么回滚的时

候,就会执行一个相反的insert,对于update,回滚的时候会执行一个相反的update,把数据再改回去。

持久性:

持久性的原理,也是通过log,叫redo log,持久性是指这个事物一旦提交,它对数据库的改变,就是永

久性的。首先说下它存在的背景,MySQL的数据,是存在磁盘中的,但是如果每次去读数据都需要经过这个磁

盘IO,那么它的效率就会很低,所以innodb提供了一个缓存buffer,这个buffer中包含了磁盘中的部分数据页

的一个映射,作为访问数据库的一个缓冲,当从数据库读取数据的时候,就会先从这个buffer中取,如果

buffer没有,再去磁盘中读取,读取完之后再放到buffer缓存中。当向数据库写入数据的时候,也会首先向

buffer中写入数据,然后定期将buffer的数据刷新到磁盘上,来完成持久化的操作。这个时候就存在一个问

题,虽然读写效率提升了,但是它也增加了数据丢失的风险,如果buffer中的数据还没有来得及同步到这个磁

盘上,这个时候MySQL宕机了,那么buffer中的数据就会丢失,进而造成数据的丢失。基于这个背景,所以

read log就被引入进来解决这个问题。改进之后的流程是这样的,当数据库的数据要进行新增和修改的时候,

除了修改这个buffer的数据,还要把这次的操作记录到read log日志里面,那么大家可以想一下,如果这个

MySQL宕机了,那么还有这个read log可以去恢复数据,read log是这个预写式日志,也就是说它会将所有

的修改先写入到日志里面,然后再更新到buffer里面,保证了数据不会丢失。既然read log也需要把事务提交

的日志写入到磁盘,那它为什么比直接将buffer中的数据写入到磁盘中要快呢?主要有两个原因,一个是

buffer中的数据持久化是随机写的,IO每次修改的数据位置,都是随机的,但是read log是追加模式的,它是

在文件的尾部去追加,属于一种顺序IO的操作,这种方式就很快,第二个就是buffer持久化数据是以数据页配

置为单位的,MySQL默认的配置页大小是16k,一个数据页上一个小小的修改都要把整个页的数据写入。而

read log只需要写入真正需要的部分就可以了,这样无效的IO就大大的减少了。所以read log要比buffer同步

数据要快的很多很多,那么read log是什么时候会同步到磁盘里去呢?read log在没有同步到磁盘之前,是在

缓冲区中的,叫做read log缓冲区,这个时候就算这个宕机了,也没有关系,因为事务没有执行完,没有去提

交,这样在恢复好数据库之后,还可以走回滚的操作,可以通过这个undo log日志去做回滚。read log的三种

持久化的机制(innodb_flush_log_at_trx_commit ):

0:表示当提交事务时,并不将缓冲区的redo日志写入磁盘的日志文件,而是等待主线程每秒刷新;

1:在事务提交时将redo日志同步写入磁盘,保证一定会写入成功(推荐的方式);

2:在事务提交时缓冲区的redo日志异步写入到磁盘,不能保证在commit时肯定会写入redo日志,只是

会有这个动作。

隔离性:

隔离性呢,又分为两种情况,一个是写写操作,还有一个是写读操作。写写操作,是通过锁去实现隔离

性,写读操作,是通过mvcc来实现。关于读的话大家应该知道,它会存在脏读,不可重复读,以及幻读的情

况,这三种情况是基于mvcc去解决的。隔离性的含义,是指不同的事物之间,它要相互不能影响,就像线程一

样,线程与线程之间是不能互相影响对方的。如果有两个事物,同时要对一行数据进行写操作,那么这时候只

有一个事务能对这个数据进行操作,这就需要锁来保证同一时刻只有一个人在操作这个数据,在这个事务修改

数据之前,要获取相应的锁,获取到锁之后,然后才可以修改这个数据,如果其他事务想操作这个数据,必须

等待当前的事务提交或者回滚之后,释放了这个锁,下一个事务才能继续来抢这个锁,去执行它的事务。关于

锁和mvcc的知识,内容比较多,后面单独一篇文章来讲。

一致性:

一致性是指这个事务执行之后,数据库的完整性约束没有被破坏,事务执行前后都是合法的一个数据状

态,比如这个数据库的主键要唯一,字段类型大小,长度要符合这要求,还有外界的约束要符合要求。这个一

致性,是事务追求的最终目标,前面所提到的原子性、持久性、隔离性,都是为了保证数据库最终状态的一致

性。

六、事务控制

1. 查看事务参数状态

show variables like '%commint%'

2. 查看事务提交模式

SELECT @@autocommit;

3. 修改事务提交模式:手动提交模式

set autocommit = false;  或  set autocommit = 0;

上面语句执行之后,它之后的所有sql,都需要手动提交才能生效,直到恢复自动提交模式。

4. 恢复自动提交模式

set autocommit = true; 或 set autocommit = 1;

5. 开启事务

START TRANSACTION 或 BEGIN;

6. 提交事务

COMMIT;

7. 回滚事务

ROLLBACK;

8. 自动提交模式下开启事务

start transaction;

(1)

....

(3)

commit; 或 rollback;   

此时,在(1)和(3)之间的语句是属于手动提交模式,其他的仍然是自动提交模式。

注意:

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

七、并发事务问题

1. 脏读

脏读即一个事务读到另外一个事务还没有提交的数据

模板一

比如B读取到了A未提交的数据。

模板二

2. 不可重复读

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

模版一

事务A两次读取同一条记录,但是读取到的数据却是不一样的。

模板二

3. 虚读/幻读

虚读/幻读即一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存

在,好像出现了 "幻影"。

模板一

模板二

4. 第一类更新

一个事务覆撤销时,把已提交的另一个事务的更新数据覆盖看(严重)

5. 第二类更新

一个事务覆盖另外一个事务已经提交的数据,造成另外一个事务所做的操作丢失

八、事务隔离级别

1. 简介

为了解决并发事务所引发的问题,在数据库中引入了事务隔离级别。

在标准 SQL 规范中定义了四种隔离级别:

READ UNCOMMITED < READ COMMITED < REPEATABLE READ < SERIALIZABLE

其中√表示可能出现的情况

2. Oracle 支持 2 种事务隔离级别

① READ-COMMITED(Oracle默认事务隔离级别)

② SERIALIZABLE

Oracle 支持 READ COMMITED(缺省)和 SERIALIZABLE

3. MySQL支持 4 种事务隔离级别

① read-uncommitted

② read-committed

③ repeatable-read(MySQL默认事务隔离级别)

④ serializable

MySQL 支持 四种隔离级别,缺省为 REPEATABLE READ,

默认情况下也不会出现幻读和第一类丢失的问题,所以只需处理第二类丢失更新的问题。

4. 隔离级别操作

查看当前会话隔离级别

SELECT @@tx_isolation;

查看系统隔离级别

select @@global.tx_isolation;

设置当前会话隔离级别

set session transaction isolation level repeatable read;

设置系统隔离级别

set global transaction isolation level repeatable read;

查看锁资源使用情况

select * from information_schema.INNODB_LOCKS;

查看锁等待

select * from information_schema.INNODB_LOCK_WAITS;

查看事务

select * from information_schema.INNODB_TRX;

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

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

相关文章

入门数据结构JAVA DS——二叉树的介绍 (构建,性质,基本操作等) (1)

前言 二叉树的概念和性质 二叉树的基本概念 二叉树的种类 二叉树的性质 二叉树的构建存储与遍历 存储 构建 遍历 前序遍历 后序遍历 中序遍历 层序遍历 二叉树的基本操作 获取树中结点个数 获取叶子结点个数 获取第K层结点的个数 获取二叉树的高度 检测值为v…

C++ —— vector 的模拟实现

目录 前言 1. vector深度剖析 2. 基础框架 3. 核心接口 3.1 reserve 3.2 push_back 和 pop_back 3.3 print 3.4 insert 3.5 erase 3.6 resize 4. 拷贝构造 4.1 构造与析构 4.2 拷贝构造 4.3 赋值重载 4.4 迭代器区间 5. 使用memcpy拷贝问题 前言 接:C —— 关于…

FX5 CPU模块和以太网模块的以太网通信功能

FX5 CPU模块和以太网模块的以太网通信功能的概要如下所示。 CPU模块的内置以太网端口的通信规格如下所示。 1、与MELSOFT的直接连接 不使用集线器&#xff0c;用1根以太网电缆直接连接以太网搭载模块与工程工具(GX Torks3)。无需设定IP地址&#xff0c;仅连接目标指定即可进行…

学习Java(一)类和对象

package demo.ceshi;public class Puppy {private int age;private String name;//构造器public Puppy( String name){this.name name;System.out.println("公主的名字叫&#xff1a;"name);}//设置age的值public void setAge(int age){this.age age;System.out.pr…

数值计算 --- 平方根倒数快速算法(中)

平方根倒数快速算法 --- 向Greg Walsh致敬&#xff01; 1&#xff0c;平方根倒数快速算法是如何选择初值的?WTF中的神秘数字究竟是怎么来的&#xff1f; 花开两朵&#xff0c;各表一枝。在前面的介绍中&#xff0c;我们已经知道了这段代码的作者在函数的最后使用了NR-iteratio…

CVE-2024-46103

前言 CVE-2024-46103 SEMCMS的sql漏洞。 漏洞简介 SEMCMS v4.8中&#xff0c;SEMCMS_Images.php的search参数&#xff0c;以及SEMCMS_Products.php的search参数&#xff0c;存在sql注入漏洞。 &#xff08;这个之前就有两个sql的cve&#xff0c;这次属于是捡漏了&#x1f6…

【MATLAB源码-第268期】基于simulink的永磁同步电机PMSM双闭环矢量控制系统SVPWM仿真,输出转速响应曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 永磁同步电机&#xff08;PMSM&#xff09;是目前工业领域中广泛使用的一种高效电机&#xff0c;其具有高功率密度、运行效率高、动态响应快等优点。在控制永磁同步电机时&#xff0c;通常采用矢量控制&#xff08;也称为磁场…

新160个crackme - 060-snake

运行分析 需破解Name和Serial PE分析 32位&#xff0c;未知程序和壳 点击Scan/t按钮外部扫描&#xff0c;发现是C程序 静态分析&动态调试 ida搜索关键字符串&#xff0c;双击进入 发现无法反编译 选中该函数&#xff08;地址&#xff1a;401048 - 401172&#xff09;Edit -…

认识结构体

目录 一.结构体类型的声明 1.结构的声明 2.定义结构体变量 3.结构体变量初始化 4.结构体的特殊声明 二.结构体对齐(重点难点) 1.结构体对齐规则 2.结构体对齐练习 (一)简单结构体对齐 (二)嵌套结构体对齐 3.为什么存在内存对齐 4.修改默认对齐数 三.结构体传参 1…

PMP--二模--解题--51-60

文章目录 14.敏捷--术语表--完成的定义DoD--它是团队需要满足的所有标准的核对单&#xff0c;只有可交付成果满足该核对单才能视为准备就绪可供客户使用。51、 [单选] 在冲刺计划会议上&#xff0c;Scrum主管重申&#xff0c;如果在冲刺结束时敏捷项目团队正在构建的产品增量没…

五种IO模型和阻塞IO

文章目录 五种 IO 模型和阻塞 IO1、五种 IO 模型1.1、阻塞 IO1.2、非阻塞 IO1.3、信号驱动 IO1.4、IO 多路转接1.5、异步 IO1.6、总结 2、高级 IO 概念2.1、同步通信&#xff08;synchronous communication&#xff09;和异步通信&#xff08;asynchronous communication&#…

第十五章:使用html、css、js编程制作一个网页版的下雪场景动画

背景:这是一个充满诗意的下雪场景代码。打开网页时,雪花轻轻飘落,覆盖住你的屏幕,仿佛置身于冬日的夜空下。背景音乐《我期待的不是雪》缓缓响起,伴随着雪花的飘动,仿佛心中的那份爱与温柔悄然绽放。 雪花的飘落是梦境般的存在,每一片雪花都是轻盈的告白,旋转着从天际…

使用GitHub Actions自动发布electron多端安装程序

GitHub Actions 是一个强大的自动化工具&#xff0c;可以帮助开发者在 GitHub 仓库中自动化构建、测试和部署工作流程。我们的客户端就是使用github action来打包项目发布的。 以下是关于 GitHub Actions 自动化构建的一些关键点和步骤&#xff1a; GitHub Actions 的基本概念…

go注册中心Eureka,注册到线上和线下,都可以访问

go注册中心Eureka&#xff0c;注册到线上和线下&#xff0c;都可以访问 本地通过127访问&#xff0c; 线上通过内网ip访问 package mainimport ("github.com/SimonWang00/goeureka""github.com/gin-gonic/gin""wbGo/controller""wbGo/task…

【工具变量】地市环保法庭试点城市DID数据集(2005-2023年)

数据简介&#xff1a;环保法庭是中国司法体系中专门处理环境资源案件的审判机构&#xff0c;其主要职责包括审理涉及自然环境污染、矿产资源保护、自然资源环境开发等环境资源民事纠纷案件&#xff0c;对不服下级人民法院生效裁判的环境资源民事案件进行审查&#xff0c;以及对…

Java_Se--方法

方法就是一个代码片段. 类似于 C 语言中的 "函数"。方法存在的意义(不要背, 重在体会): 1. 是能够模块化的组织代码 ( 当代码规模比较复杂的时候 ). 2. 做到代码被重复使用 , 一份代码可以在多个位置使用 . 3. 让代码更好理解更简单 . 4. 直接调用现有方法开…

cv中每个patch的关联

在计算机视觉任务中&#xff0c;当图像被划分为多个小块&#xff08;patches&#xff09;时&#xff0c;每个 patch 的关联性可以通过不同的方法来计算。具体取决于使用的模型和任务&#xff0c;以下是一些常见的计算 patch 关联性的方法&#xff1a; 1. Vision Transformer (…

IDA Pro-代码结构识别

Lab06-01.exe分析 1.由main 函数调用的唯一子过程中发现的主要代码结构是什么? if语句结构 找到main函数中唯一调用的函数&#xff0c;并进入 判断网络是否链接成功&#xff0c;如果返回0走右边未连接成功 2.位于0x40105F的子过程是什么? 将字符串压栈&#xff0c;猜测…

双非本 985 硕士,秋招上岸字节算法岗!

最近已有不少大厂都在秋招宣讲了&#xff0c;也有一些在 Offer 发放阶段。 节前&#xff0c;我们邀请了一些互联网大厂朋友、今年参加社招和校招面试的同学。 针对新人如何快速入门算法岗、如何准备面试攻略、面试常考点、大模型项目落地经验分享等热门话题进行了深入的讨论。…

面向对象程序设计——set容器の简析

1.set的介绍 • 序列式容器和关联式容器 • 我们已经接触过STL中的部分容器如&#xff1a;string、vector、list、deque、array、forward_list等&#xff0c;这些容器统称为序列式容器&#xff0c;因为逻辑结构为线性序列的数据结构&#xff0c;两个位置存储的值之间⼀般没有紧…