MySQL数据库精研之旅第十七期:深度拆解事务核心(下)

专栏:MySQL数据库成长记

个人主页:手握风云

目录

一、事务的隔离性和隔离级别

[1.1. 什么是隔离性](#1.1. 什么是隔离性)

[1.2. 隔离级别](#1.2. 隔离级别)

[1.3. 不同隔离级别存在的问题](#1.3. 不同隔离级别存在的问题)

[1.3.1. READ UNCOMMITTED------读未提交](#1.3.1. READ UNCOMMITTED——读未提交)

[1.3.2. READ COMMITTED------读已提交](#1.3.2. READ COMMITTED——读已提交)

[1.3.3. REPEATABLE READ------可重复读](#1.3.3. REPEATABLE READ——可重复读)

[1.3.4. SERIALIZABLE------串行化](#1.3.4. SERIALIZABLE——串行化)

[1.4. 不同隔离级别的性能与安全](#1.4. 不同隔离级别的性能与安全)

[1.5. 查看和设置隔离级别](#1.5. 查看和设置隔离级别)


一、事务的隔离性和隔离级别

1.1. 什么是隔离性

MySOL服务可以同时被多个客户端访问,每个客户端执行的DML语句以事务为基本单位,那么不同的客户端在对同一张表中的同一条数据进行修改的时候就可能出现相互影响的情况,为了保证不同的事务之间在执行的过程中不受影响,那么事务之间就需要要相互隔离,这种特性就是隔离性。

1.2. 隔离级别

事务具有隔离性,那么如何实现事务之间的隔离?隔离到什么程度?如何保证数据安全的同时也要兼顾性能?

事务间不同程度的隔离,称为事务的隔离级别;不同的隔离级别在性能和安全方面做了取舍,有的隔离级别注重并发性,有的注重安全性,有的则是并发和安全适中;在MySQL的InnoDB引擎中事务的隔离级别有四种,分别是:

  1. READ UNCOMMITTED,读未提交。
  2. READ COMMITTED,读已提交。
  3. REPEATABLE READ,可重复读。
  4. SERIALIZABLE,串行化。

1.3. 不同隔离级别存在的问题

1.3.1. READ UNCOMMITTED------读未提交

事务A对数据进行了修改,事务B可以访问到事务A还没有提交的数据(也就是可能发生回滚),这个现象叫做"脏读"。

1.3.2. READ COMMITTED------读已提交

在工作中,程序员需要经常使用git提交项目,如果其他同事在查看的过程中,上传者对其进行了修改。事务A在一个事务对同一条记录查询了两次,在两次查询之间事务B对数据进行了修改并提交了事务,那么事务A就会查询到两条不同的结果,这种现象就是"不可重复读"。

1.3.3. REPEATABLE READ------可重复读

当一个程序员在去修改项目时,突然领导说先不要上传,看完之后再改,这个过程就相当于加了一把锁。但是程序员还可以对其他文件进行修改(增、删),导致仓库中的文件列表不一样,那么领导第一次查询的列表内容与第二次查询到的列表内容不一致。务A第一次查询到的结果集)与第二次查询到的结果集不一致,这个现象叫"幻读"。

在Innodb存储引擎中,使用了next-key锁,锁住了目标行与之前的间隙,解决了部分的幻读问题。

1.3.4. SERIALIZABLE------串行化

可以解决所有的数据安全问题,所有的事务是一个接一个的执行,一个事务必须要等到上一个事务执行完成之后才执行。

1.4. 不同隔离级别的性能与安全

|------------------------|------|-----------|---------------|-------------------------------------|
| 隔离级别(Isolation Level) | 并发性能 | 隔离力度(安全性) | 解决的问题 | 存在的问题 |
| READ UNCOMMITTED(读未提交) | 最高 | 最低 | 无(不解决任何并发问题) | 存在脏读、不可重复读、幻读 |
| READ COMMITTED(读已提交) | 较高 | 较低 | 解决脏读 | 存在不可重复读、幻读 |
| REPEATABLE READ(可重复读) | 中等 | 较高 | 解决脏读、不可重复读 | (InnoDB 中通过 Next-Key 锁大幅缓解幻读,基本无幻读) |
| SERIALIZABLE(串行化) | 最低 | 最高 | 解决脏读、不可重复读、幻读 | 无(完全避免并发问题) |

并发性能 指数据库同时处理多个事务的能力,串行化因强制事务排队执行,性能最差。**隔离力度(安全性)**指事务间相互隔离、避免数据不一致的能力,行化因完全隔绝并发,安全性最高。

1.5. 查看和设置隔离级别

  • 事务的隔离级别分为全局作用域和会话作用域,全局作用域下的事务隔离级别设置会影响后续所有新启动的数据库连接和事务。会话作用域仅对当前数据库会话(即一个客户端与数据库建立的连接期间)内的事务有效。
sql 复制代码
-- 全局作用域
SELECT @@GLOBAL.transaction_isolation;
-- 会话作用域
SELECT @@SESSION.transaction_isolation;
  • 设置事务的隔离级别和访问模式
sql 复制代码
SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL level|access_mode;

方括号 [] 内为可选参数 ,不指定时默认作用于 "下一个事务"(仅对后续第一个事务生效,之后恢复原有设置)。level:表示事务隔离级别(必选,需从指定选项中选择)。access_mode:表示事务访问模式(可选,控制事务是否允许读写操作)。

sql 复制代码
-- 1. 设置全局隔离级别为"串行化"(影响后续所有新连接,不影响当前事务)
SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;

-- 2. 设置会话隔离级别为"串行化"(影响当前会话后续所有事务,不影响其他会话)
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;

-- 3. 设置"仅下一个事务"的隔离级别为"串行化"(临时生效,后续事务恢复原级别)
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
sql 复制代码
-- 1. 方式一:直接赋值给transaction_isolation变量
-- 设置全局隔离级别为"串行化"
SET GLOBAL transaction_isolation = 'SERIALIZABLE';
-- 设置会话隔离级别为"可重复读"(空格替换为"-",即REPEATABLE-READ)
SET SESSION transaction_isolation = 'REPEATABLE-READ';

-- 2. 方式二:通过@@变量名赋值
-- 设置全局隔离级别为"串行化"
SET @@GLOBAL.transaction_isolation = 'SERIALIZABLE';
-- 设置会话隔离级别为"可重复读"(空格替换为"-")
SET @@SESSION.transaction_isolation = 'REPEATABLE-READ';
相关推荐
进阶的小木桩9 分钟前
mysql 安装问题解决方案记录
数据库·mysql
2601_962071571 小时前
如何利用SpringSecurity进行认证与授权
java·服务器·数据库
dazhong20121 小时前
Docker 入门篇(八)-- CentOS7 安装 MySQL 8
mysql·docker·容器
山峰哥1 小时前
数据库工程与查询优化案例深度复盘‌
数据库·sql·oracle·编辑器·深度优先·宽度优先
IT大白鼠1 小时前
MSF数据库与资产管理——专业渗透测试流程
数据库·安全·msf
IvorySQL1 小时前
PostgreSQL 日报|内核多项缺陷修复与数据校验补丁推进(8 月 27 日)
数据库·postgresql·区块链
风吹心凉1 小时前
Agent大脑-RAG知识库
数据库
VALENIAN瓦伦尼安教学设备2 小时前
设备状态检测振动分析实训台案例分析
大数据·数据库·人工智能·嵌入式硬件·算法
黄俊懿2 小时前
【架构师从入门到进阶】第五章:DNS&CDN&网关优化思路——第十节:网关安全-单向加密
网络·数据库·计算机网络·安全·架构·系统架构·架构师
garmin Chen2 小时前
redis面试题
java·数据库·redis·缓存