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 | 不存在 | 不存在 | 不存在 |

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

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

相关推荐
king_harry1 小时前
openGauss 6.0 主备集群备份与恢复实战指南:基于 gs_probackup
数据库·opengauss·gs_probackup
ruxshui1 小时前
MySQL备份核心指南
数据库·mysql
霖霖总总2 小时前
[小技巧73]MySQL UUID 全面解析:UUID 的原理、结构与最佳实践
数据库·mysql
tod1132 小时前
Redis C++ 客户端开发全流程指南
数据库·c++·redis·缓存
w_t_y_y2 小时前
MySQL原理(三)锁定机制(4)常见的行锁行为&影响哪些操作&对DB的影响
数据库
沧澜sincerely2 小时前
组合查询(UNION)
数据库·union·union all
爬山算法3 小时前
MongoDB(10)如何安装MongoDB?
数据库·mongodb