【MySQL】深度学习数据库开发技术:mysql事务穿透式解析

**前言:**本节内容开始讲解事务。 博主计划用三节来讲解事务。 本篇为第一节, 主要解释什么是事务, 事务有什么用。 以及事物的基本操作和异常退出回滚情况。 下面不多说,友友们, 开始学习吧!

ps:本节内容建议友友们学会表的操作后再来学习哦, 会学的轻松很多!

目录

什么是事务

[CURD满足什么性质, 才能解决上面的问题呢?](#CURD满足什么性质, 才能解决上面的问题呢?)

MySQL事务维护的四大属性

为什么会出现事务

实际操作准备工作

事务正式操作

[rollback to](#rollback to)

rollback

commit持久化

事务异常

自动提交和不自动提交


什么是事务

我们现实大部分都是一组sql,才能将一系列操作给做出来。在我们程序员的眼中,一条sql就是一条操作。但是对于上层用户来说,往往几条sql来完成某个逻辑,就比如买票。 而这几条sql,我们就称为事务。所以,事务的本质要站在mysql的上层来看,就是一条或者多条sql组合起来完成某种逻辑的集合体。

并且,对于数据库的CURD来说,我们的买票场景, 可能就有时候只剩下一张票, 这时候来了一个人买票, 但是还没有更新数据。此时又来了一个客户端, 发现票数大于0, 就又买了一次票。 但是当两个客户端都更新数据的时候, 发现票数变为了-1。 这个时候就发生错误了, 相当于多卖了一张票。 所以, 事务就出现了。

CURD满足什么性质, 才能解决上面的问题呢?

  • 买票的过程是原子的;
  • 买票的过程不应该互相影响;
  • 买完票应该是永久的;
  • 买完票后的状态应该是确定的;

MySQL事务维护的四大属性

  • 原子性:要么完成, 要么不完成。
  • 一致性:一致性就是一个事务开始和开始之后, 我们用户数据的完整性没有被破坏。在mysql中, 对于一致性没有更多的操作。他只要做好原子性、隔离性、持久性、就能在技术层面上完成一致性。
  • 隔离性:数据库允许多个事务同时对数据进行修改和读写。隔离性可以将一个一个的事务隔离开, 就能让事务之间不会彼此影响。事物的隔离性存在不同的分级。
  • 持久性:事务处理完之后, 对于数据的修改就是永久的。即使是系统故障也不会丢失。

这四大属性被称为ACID

为什么会出现事务

事务是被mysql编辑着设计出来的。的按时事务不是天然就有的, 而是当mysql被写出来之后, 发现需要这个东西。另外, 他是为了让我们的C/C++或者java, python这种用起来更加方便, 简化编程模型, 要么提交, 要么回滚。 我们不去考虑宕机, 网络异常各种情况。 所以, 事物本身就是为了应用层服务的。

实际操作准备工作

在mysql中, InnoDB支持事务, 但是MyISAM是不支持事物的。

事务有两种提交方式:一种叫手动提交, 一种叫自动提交。

未来我们有事务,我们得自己提交。 mysql中事务的提交方式有两种:默认提交,手动提交。 如何查看当前事务的提交方式?

使用指令:

sql 复制代码
show variables like 'autocommit';

然后我们进行测试的时候, 我们的隔离级别, 先设置成读未提交。 后面我们在来讲解这些不同的隔离级别:

sql 复制代码
set global transaction isolation level read uncommitted;

然后查看当前的隔离级别:

sql 复制代码
select @@transaction_isolation;

然后创建一个下面这样的表:

sql 复制代码
create table if not exists account(
id int primary key,
name varchar(50) not null default '',
blance decimal(10, 2) not null default 0.0
);

事务正式操作

利用一个案例来看如何操作事务:

rollback to

我们先启动事务

sql 复制代码
start transaction;

设置保存点

sql 复制代码
savapoint 名称;

插入数据之后再设置一个保存点

sql 复制代码
insert into account values(1, '张三', 1234.5);
savepoint s2;

然后再插入数据, 同时设置保存点:

sql 复制代码
insert into account values(2, '李四', 4321.6);
savepoint s3;
insert into account values(3, '王五', 5432.7);

此时观看表中, 就看到数据都插入进来了:

问题是, 如果今天我后悔了, 我不想插入李四和王五了。 我们怎么做呢? 就可以使用定向回滚, 回滚到我们设置的某一个保存点处。

sql 复制代码
rollback to s2;

我们再查看表中数据, 就没有李四和王五了!

然后事务结束之后, 我们不想要回滚了, 就像直接提交了。 我们就可以使用commit

sql 复制代码
commit;

rollback

然后我们也可以直接rollback把从开始到目前所做的操作全部放弃掉。

sql 复制代码
start transaction;
insert into account values(1, '张三', 1234.5);
insert into account values(2, '李四', 4321.6);
insert into account values(3, '王五', 5432.7);
sql 复制代码
rollback;

commit持久化

然后我们再启动事务。 这一次我们插入数据后直接提交。 然后再回滚:

sql 复制代码
start transaction;
insert into account values(2, '李四', 4321.6);
insert into account values(3, '王五', 5432.7);
commit;
//ctrl + \

我们就会看到, 即便我们进行了回滚,数据也没有变化。 即:只要事务提交了, 就完成了持久化, 事务无法回滚!!!

事务异常

我们要做的实验就是我们正在启动有一个事务。 但是客户端挂掉了, 莫名崩溃掉了。 这个时候mysql是怎么处理的。 所以我们就先插入一条数据, 然后ctrl + '\', 让mysql客户端崩溃。 如下:

sql 复制代码
start transaction;
insert into account values(4, '赵六', 6666.6);

然后我们再查看表数据, 会发现, 新插入的数据没有提交, 没有持久化。 也就是完成了自动回滚。

直接关掉终端也是一样的, 但是截图不了。 友友们自行测试。
这一次, 我们先commit, 再异常退出:

sql 复制代码
start transaction;
insert into account values(4, '赵六', 6666.6);
commit;
//ctrl + \

结果可以预见, 完成了持久化:

默认情况下, 提交方式是自动提交:

sql 复制代码
show variables like'autocommit';

但是, 对于事物的提交类型。 自动提交不影响我们的begin和commit。 对于begin也就是手动开启的事务来说, 我们收到开启, 就得手动commit。也就是说, 即便我们将set autocommit = 0,结果也不会有什么不同。

自动提交和不自动提交

现在我们来谈一下自动提交和不自动提交有什么用。 现在来一组对比试验:

先看自动提交:

sql 复制代码
show variables like 'autocommit';

我们再另一个客户端上面启动一个事务, 然后查看当前表的数据:

然后回到原来的客户端删掉id为1的数据:

sql 复制代码
delete from account where id = 1;

这个时候我们终止这个客户端。

sql 复制代码
show variables like'autocommit';

然后去另一个客户端查看表数据, 会发现, 刚刚删掉的数据确实没了:

这个符合我们的预期。

但是我们再来看另一个实验, 这个时候设置为手动提交:

设置手动提交, 然后删除数据, 最后终止客户端。

sql 复制代码
set autocommit = 0;
delete from account where id = 2;
//ctrl + \

我们去检查另一个客户端的数据,表中数据是否被删除:

可以看到, 并没有被删除。

**通过上面我们的现象, 我们可以猜测, autocommit影响的是我们的单sql。 其实我们以前的sql语句, 都是一个事务。 这个事务默认是自动提交的。**并且我们能看到mysql的两大特性。 一个是原子性, 一个是持久性。

------------------以上就是本节全部内容哦, 如果对友友们有帮助的话可以关注博主, 方便学习更多知识哦!!!

相关推荐
King.6248 分钟前
SQLynx 数据库管理平台 3.6.0 全新发布:全面支持华为数据库和ClickHouse,代码提示更智能!
大数据·数据库·人工智能·sql·mysql·clickhouse·华为
太阳伞下的阿呆1 小时前
CentOS 8 如何安装java与mysql
java·mysql·centos
小希与阿树1 小时前
如何解决Redis中的热点key问题
数据库·redis·缓存
林犀居士3 小时前
H2数据库在单元测试中的应用
数据库·单元测试·h2·内存数据库
苹果酱05676 小时前
Golang的文件加密技术研究与应用
java·vue.js·spring boot·mysql·课程设计
周周写不完的代码6 小时前
mysql -> 达梦数据迁移(mbp大小写问题兼容)
数据库·mysql·达梦
跳跳的向阳花9 小时前
05、Docker学习,常用安装:Mysql、Redis、Nginx、Nacos
学习·mysql·docker
MiniFlyZt10 小时前
省市区三级联动(后端)
数据库·spring boot
背太阳的牧羊人10 小时前
用于与多个数据库聊天的智能 SQL 代理问答和 RAG 系统(2) —— 从 PDF 文档生成矢量数据库 (VectorDB),然后存储文本的嵌入向量
数据库·人工智能·sql·langchain·pdf
计算机毕设指导611 小时前
基于Springboot的景区民宿预约系统【附源码】
java·开发语言·spring boot·后端·mysql·spring·intellij idea