炸裂!MySQL 82 张图带你飞!(一)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 这篇文章我们来了解一下 MySQL 中的高级内容。

事务控制和锁定语句

我们知道,MyISAM 和 MEMORY 存储引擎支持表级锁定(table-level locking),InnoDB 存储引擎支持行级锁定(row-level locking),BDB 存储引擎支持页级锁定(page-level locking)。各个锁定级别的特点如下

页级锁:销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般

表级锁:表级锁是对整张表进行加锁,MyISAM 和 MEMORY 主要支持表级锁,表级锁加锁快,不会出现死锁,锁的粒度比较粗,并发度最低

行级锁:行级锁可以说是 MySQL 中粒度最细的一种锁了,InnoDB 支持行级锁,行级锁容易发生死锁,并发度比较好,同时锁的开销也比较大。

MySQL 默认情况下支持表级锁定和行级锁定。但是在某些情况下需要手动控制事务以确保整个事务的完整性,下面我们就来探讨一下事务控制。但是在探讨事务控制之前我们先来认识一下两个锁定语句

锁定语句

MySQL 的锁定语句主要有两个 LockunLock,Lock Tables 可用于锁定当前线程的表,就跟 Java 语法中的 Lock 锁的用法是一样的,如果表锁定,意味着其他线程不能再操作表,直到锁定被释放为止。如下图所示

lock table cxuan005 read;

微信图片_20220418192550.png

我们锁定了 cxuan005 的 read 锁,然后这时我们再进行一次查询,看看是否能够执行这条语句

select * from cxuan005 where id = 111;

微信图片_20220418192554.png

可以看到,在进行 read 锁定了,我们仍旧能够执行查询语句。

现在我们另外起一个窗口,相当于另起了一个线程来进行查询操作。

select * from cxuan005;

微信图片_20220418192558.png

这是第二个窗口执行查询的结果,可以看到,在一个线程执行 read 锁定后,其他线程仍然可以进行表的查询操作。

那么第二个线程能否执行更新操作呢?我们来看一下

update cxuan005 set info='cxuan' where id = 111;

微信图片_20220418192602.png

发生了什么?怎么没有提示结果呢?其实这个情况下表示 cxuan005 已经被加上了 read 锁,由于当前线程不是持有锁的线程,所以当前线程无法执行更新。

解锁语句

现在我们把窗口切换成持有 read 锁的线程,来进行 read 锁的解锁

unlock tables;

微信图片_20220418192605.png

在解锁完成前,进行更新的线程会一直等待,直到解锁完成后,才会进行更新。我们可以看一下更新线程的结果。

微信图片_20220418192608.png

可以看到,线程已经更新完毕,我们看一下更新的结果

select * from cxuan005 where id = 111;

微信图片_20220418192612.png

如上图所示,id = 111 的值已经被更新成了 cxuan。

事务控制

事务(Transaction) 是访问和更新数据库的基本执行单元,一个事务中可能会包含多个 SQL 语句,事务中的这些 SQL 语句要么都执行,要么都不执行,而 MySQL 它是一个关系型数据库,它自然也是支持事务的。事务同时也是区分关系型数据库和非关系型数据库的一个重要的方面。

在 MySQL 事务中,主要涉及的语法包含 SET AUTOCOMMIT、START TRANSACTION、COMMIT 和 ROLLBACK 等。

自动提交

在 MySQL 中,事务默认是自动提交(Autocommit)的,如下所示

show variables like 'autocommit';

微信图片_20220418192616.png

在自动提交的模式下,每个 SQL 语句都会当作一个事务执行提交操作,例如我们上面使用的更新语句

update cxuan005 set info='cxuan' where id = 111;

如果想要关闭数据库的自动提交应该怎么做呢?

其实,MySQL 是可以关闭自动提交的,你可以执行

set autocommit = 0;

微信图片_20220418192619.png

然后我们再看一下自动提交是否关闭了,再次执行一下 show variables like 'autocommit' 语句

微信图片_20220418192624.png

可以看到,自动提交已经关闭了,再次执行

set autocommit = 1;

会再次开启自动提交。

这里注意一下特殊操作。

在 MySQL 中,存在一些特殊的命令,如果在事务中执行了这些命令,会马上强制执行 commit 提交事务;比如 DDL 语句(create table/drop table/alter/table)、lock tables 语句等等。

不过,常用的 select、insert、update 和 delete命令,都不会强制提交事务。

手动提交

如果需要手动 commit 和 rollback 的话,就需要明确的事务控制语句了。

典型的 MySQL 事务操作如下

start transaction;
... # 一条或者多条语句
commit;

上面代码中的 start transaction 就是事务的开始语句,编写 SQL 后会调用 commit 提交事务,然后将事务统一执行,如果 SQL 语句出现错误会自动调用 Rollback 进行回滚。

下面我们就通过示例来演示一下 MySQL 的事务,同样的,我们需要启动两个窗口来演示,为了便于区分,我们使用 mysql01 和 mysql02 来命名。

微信图片_20220418192627.png

我们用 start transaction 命令启动一个事务,然后在 cxuan005 表中插入一条数据,此时 mysql02 不做任何操作。涉及的 SQL 语句如下。

start transaction;

微信图片_20220418192631.png

然后执行

select * from cxuan005;

查询一下 cxuan005 中的数据

微信图片_20220418192634.png

嗯。。。很多长度太长了,现在我们把所有的 info 数据都更新为 cxuan 。

update cxuan005 set info='cxuan';

微信图片_20220418192637.png

更新完毕后,我们先不提交事务,分别在 mysql01 和 mysql02 中进行查询,发现只有 mysql01 窗口中的查询已经生效,而 mysql02 中还是更新前的数据

微信图片_20220418192637.png

现在我们在 mysql01 中 commit 当前事务,然后在 mysql02 中查询,发现数据已经被修改了。

除了 commit 之外,MySQL 中还有 commit and chain 命令,这个命令会提交当前事务并且重新开启一个新的事务。如下代码所示

start transaction; # 开启一个新的事务
insert into cxuan005(id,info) values (555,'cxuan005'); # 插入一条数据
commit and chain; # 提交当前事务并重新开启一个事务

上面是一个事务操作,在 commit and chain 键入后,我们可以再次执行 SQL 语句

update cxuan005 set info = 'cxuan' where id = 555;
commit;

然后再次查询

select * from cxuan005;

微信图片_20220418192642.png

执行后,可以发现,我们仅仅使用了一个 start transaction 命令就执行了两次事务操作。

如果在手动提交的事务中,你发现有一条 SQL 语句写的不正确或者有其他原因需要回滚,那么此时你就会用到 rollback 语句,它会回滚当前事务,相当于什么也没发生。如下代码所示。

start transaction;
delete from cxuan005 where id = 555;
rollback;

这里切忌一点:delete 删除语句一定要加 where ,不加 where 语句的删除就是耍流氓。

在同一个事务操作中,最好使用相同存储引擎的表,如果使用不同存储引擎的表后,rollback 语句会对非事务类型的表进行特别处理,因此 commit 、rollback 只能对事务类型的表进行提交和回滚。

我们提交的事务一般都会被记录到二进制的日志中,但是如果一个事务中包含非事务类型的表,那么回滚操作也会被记录到二进制日志中,以确保非事务类型的表可以被复制到从数据库中。

这里解释一下什么是事务表和非事务表

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
NoSQL 数据可视化 关系型数据库
推荐几个好用的redis可视化工具
推荐几个好用的redis可视化工具
16887 1
|
2月前
|
存储 人工智能 Shell
Lua与C语言接口编程实战指南:打造高性能、灵活的程序
本文深入介绍了 Lua 与 C 语言的交互机制,重点分析了 Lua 作为胶水语言在嵌入式系统、游戏开发(如 Skynet、OpenResty)中的应用。内容涵盖 Lua 环境搭建、虚拟栈管理、C 与 Lua 的相互调用、闭包、Userdata 和注册表的使用等核心技术,并结合代码示例讲解了如何在实际项目中实现 Lua 与 C 的高效交互,适合希望掌握 Lua 扩展与嵌入开发的工程师参考学习。
140 0
|
Nacos
Nacos 配置文件属性说明
Nacos 配置文件属性说明
386 0
|
关系型数据库 MySQL 开发工具
MySQL中忘记用户密码怎么办?
MySQL中忘记用户密码怎么办?
|
负载均衡 安全 前端开发
原创好文!亿级流量网关设计思路(一)
本文准备围绕七个点来讲网关,分别是网关的基本概念、网关设计思路、网关设计重点、流量网关、业务网关、常见网关对比,对基础概念熟悉的朋友可以根据目录查看自己感兴趣的部分
原创好文!亿级流量网关设计思路(一)
|
存储 安全 Java
程序员需要了解的硬核知识之汇编语言(全)(四)
之前的系列文章从 CPU 和内存方面简单介绍了一下汇编语言,但是还没有系统的了解一下汇编语言,汇编语言作为第二代计算机语言,会用一些容易理解和记忆的字母,单词来代替一个特定的指令,作为高级编程语言的基础,有必要系统的了解一下汇编语言,那么本篇文章希望大家跟我一起来了解一下汇编语言。
290 0
程序员需要了解的硬核知识之汇编语言(全)(四)
|
存储 编译器 程序员
程序员需要了解的硬核知识之汇编语言(全)(三)
之前的系列文章从 CPU 和内存方面简单介绍了一下汇编语言,但是还没有系统的了解一下汇编语言,汇编语言作为第二代计算机语言,会用一些容易理解和记忆的字母,单词来代替一个特定的指令,作为高级编程语言的基础,有必要系统的了解一下汇编语言,那么本篇文章希望大家跟我一起来了解一下汇编语言。
200 0
程序员需要了解的硬核知识之汇编语言(全)(三)
|
存储 程序员 编译器
程序员需要了解的硬核知识之汇编语言(全)(二)
之前的系列文章从 CPU 和内存方面简单介绍了一下汇编语言,但是还没有系统的了解一下汇编语言,汇编语言作为第二代计算机语言,会用一些容易理解和记忆的字母,单词来代替一个特定的指令,作为高级编程语言的基础,有必要系统的了解一下汇编语言,那么本篇文章希望大家跟我一起来了解一下汇编语言。
128 0
程序员需要了解的硬核知识之汇编语言(全)(二)
呵,Semaphore ,就这?(二)
那么本篇文章我们继续来和你聊聊并发工具类的第二篇文章 --- Semaphore 。
呵,Semaphore ,就这?(二)
|
监控 前端开发 IDE
原创好文!亿级流量网关设计思路(三)
本文准备围绕七个点来讲网关,分别是网关的基本概念、网关设计思路、网关设计重点、流量网关、业务网关、常见网关对比,对基础概念熟悉的朋友可以根据目录查看自己感兴趣的部分
原创好文!亿级流量网关设计思路(三)