MYSQL---事务

(一).事务的概念

事务是把一组SQL语句打包成一个整体,在这组SQL语句的执行过程中,要么全部成功,要么全部失败。

(二).事务的ACID特性

事务的ACID 特性指的是Atomicity(原子性)Consistency(一致性)Isolation(隔离性)Durability(持久性)

1.Atomicity(原子性)

所执行的SQL语句要么全部成功,要么全部失败 ,不会出现执行一半的情况,如果事务在执行过程中出现错误,事务就会回滚(Rollback)到事务刚开始的状态,就像事务没有执行过一样。原子性是支持事务的数据库中最基本的一个特性。

2.Consistency(一致性):

事务执行完成后,保证数据正确并且符合预期

3.Isolation(隔离性):

多个事务之间不能相互影响

示例:

4.Durability(持久性):

将提交后的事务保存到存储介质中,不管数据库是否损坏,都不会影响数据的安全

(三).事务的使用

1.查看mysql当前支持的存储引擎

show engines;

2.使用事务的语法

sql 复制代码
-- 开始新的事务
start transaction; -- 或者 begin;


-- 提交当前事务,并对更改持久化保存
commit;

-- 回滚当前事务,取消对其更改
rollback;

注意:无论事务提交还是回滚,事务都会关闭。同时,开启一个事务之后,所写的SQL语句就包含在当前事务当中,这些事务具有ACID特性。

示例:

这是我创建的用于做示例的余额表

(1).测试回滚
(2).测试提交

3.保存点

在事务执行的过程中设置保存点,回滚时指定保存点可以把数据恢复到保存点的状态。

语法:

设置保存点:SAVEPOINT SP1; SP1 为保存点的名字

回滚到第二个保存点:ROLLBACK TO SP2;

回滚到事务的初始状态:ROLLBACK

图解:

示例:

4.自动/手动提交事务

(1).自动提交事务

MYSQL默认情况下是自动开启提交和回滚的

查看是否自动开启提交和回滚

show variables like 'autocommit';

autocommit : 系统变量,表示事务是否自动提交

(2).设置事务为自动提交或者手动提交

sql 复制代码
-- 设置事务自动提交
set autocommit =1;
set autocommit=on;

-- 设置事务手动提交
set autocommit=0;
set autocommit=off;

注意:

①.当使用start transaction 或 begin开启事务,就必须要通过commit 提交事务才会持久化,或者通过rollback回滚事务,才能结束事务,与是否检查set autocommit无关

②.当设置成手动提交事务后,不需要开启事务,主席那个修改操作后,提交或者回滚事务时直接使用commit或者rollback即可

③.已经commit的事务不可以再rollback

5.事务的隔离级别

(1).概念

事务间不同程度的隔离称为事务的隔离级别。事务的不同隔离级别在安全和性能都有差距,有的隔离级别注重并发性,有的隔离级别注重安全性,有的则是并发性和安全性适中,在Mysql的InnoDB的存储引擎中事务的隔离级别有四种:

READ UNCOMMITED ,读未提交

READ COMMITED,读已提交

REPEATABLE READ,可重复读(默认)

SERIALIZABLE,串行化

从高到低安全性越来越高,性能越来越低

(2).查看隔离级别

Ⅰ.查看全局的隔离级别

select @@global.transaction_isolation;

@@表示 "查看系统变量"

global 表示 "全局系统变量"所有会话都生效

Ⅱ.查看当前会话的隔离级别

select @@session.transaction_isolation;

session 表示 "当前会话生效"

(3).设置不同的隔离级别

Ⅰ.语法

SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL level | access_mode

level 表示 "隔离级别",即上面介绍的四种隔离级别

access_mode 表示 "访问模式" ,有READ WRITE 和 READ ONLY,READ WRITE表示可以对数据进行读写,READ ONLY 表示只能读,不能写

方式1:SET GLOBAL TRANSACTION ISOLATION LEVEL level;

方式2:SET GLOBAL.TRANSACTION_ISOLATION = ' level ';

方式3:SET @@GLOBAL.TRANSACTION_ISOLATION = ' level ';

注意:使用方式2和方式3的时候,如果level对应的隔离级别有空格,则用"-"代替空格

Ⅱ.不同的隔离级别以及存在的问题

下面的演示会在两个会话的条件下进行演示

①.READ UNCOMMITTED 读未提交

事务A对数据进行了修改,然后事务B读取了事务A还未提交的数据,这个情况称为 "脏读",即事务B访问了事务A rollback的数据。"脏读"读取的数据并不是错误的数据,而是修改了还未保存的数据。

演示:

此时,两个会话中的隔离级别都是 "读未提交"

通过上面的图片可以看出,会话B访问了会话A 中还未保存的数据,此时这种情况就称为 "脏读",即读取的数据不准确。

②.READ COMMITTED 读已提交

事务B一开始读取了某些数据记录,然后事务A对这些数据记录进行了修改并提交,当事务B再次查询这些数据的时候发现与第一次查询的结果不一致,此时这个现象就叫做 "不可重复读"。

演示

此时,两个会话的隔离级别都是 "读已提交"

③.REPEATABLE READ 可重复读

事务A第一次查询了某个结果集,然后第二次以相同的方式查询得到的结果集,发现与第一次查询到的结果不同,两次查询到的结果集的结果不同,此时这种现象就叫做 "幻读"。

注意:InnoDB存储引擎中,使用了next-key锁,锁住了目标行和之前的间隙,解决了部分幻读的我问题。

演示:

由于可重复读的next-key锁配合着mysql的MVCC解决了部分 "幻读问题",所以这里还是先使用 "读已提交"的隔离级别先来演示一下 "幻读"。

隔离级别依旧是 "读已提交"

间隙里面插入数据,导致两次查询的结果不一致,此时这个现象就叫做幻读

先将 隔离级别修改为 "可重复读"

④.串行化

串行化是隔离程度的最高级别,两个事务互不影响。

一个事务进行CRUD 操作的时候,不会影响到其他事务对同一个表的查询,也就是串行化不存在脏读,不可重复读、幻读的隔离问题。

总结

|------------------|--------|-----------|--------|
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
| READ UNCOMMITTED | 存在 | 存在 | 存在 |
| READ COMMITTED | 不存在 | 存在 | 存在 |
| REPEATABLE READ | 不存在 | 不存在 | 存在 |
| SERIALIZABLE | 不存在 | 不存在 | 不存在 |

从上到下,性能越来越低安全性越来越高

从下到上,性能越来越低安全性越来越高

相关推荐
随风飘的云4 小时前
MySQL的慢查询优化解决思路
数据库
IvorySQL8 小时前
PostgreSQL 技术日报 (3月7日)|生态更新与内核性能讨论
数据库·postgresql·开源
赵渝强老师9 小时前
【赵渝强老师】金仓数据库的数据文件
数据库·国产数据库·kingbase·金仓数据库
随逸17712 小时前
《Milvus向量数据库从入门到实战,手把手搭建语义检索系统》
数据库
神秘的猪头13 小时前
🚀 React 开发者进阶:RAG 核心——手把手带你玩转 Milvus 向量数据库
数据库·后端·llm
0xDevNull1 天前
MySQL索引进阶用法
后端·mysql
0xDevNull1 天前
MySQL索引用法
mysql
IvorySQL1 天前
PostgreSQL 技术日报 (3月6日)|为什么 Ctrl-C 在 psql 里让人不安?
数据库·postgresql·开源
NineData1 天前
数据库管理工具NineData,一年进化成为数万+开发者的首选数据库工具?
运维·数据结构·数据库