MySQL进阶(再论事务)——什么是事务 & 事务的隔离级别 & 结合MySQL案例详细分析(1)

最后

这份清华大牛整理的进大厂必备的redis视频、面试题和技术文档

祝大家早日进入大厂,拿到满意的薪资和职级~~~加油!!

感谢大家的支持!!

image.png

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

保存点SAVEPOINT

在事务中创建保存点,方便后续针对保存点进行回滚。一个事务中可以存在多个保存点。

在这里插入图片描述

回滚到指定位置

在这里插入图片描述

begin;
delete from account where name='zs';
savepoint first;
delete from account where name='lisi';

ROLLBACK TO first;
COMMIT

2、隐式事物

DROP TABLE account;
create table account(
    id int primary key auto\_increment,
    name varchar(20) unique not null,
    balance int
);

insert into account values(null,'zs',1000);
insert into account values(null,'lisi',1);

(1)在MySQL中执行DML语句,会自动提交事物。

delete from account where name='zs';

在这里插入图片描述

(2)MySQL中有一个系统变量 autocommit, 可以查看是否开启自动提交事物。

SHOW VARIABLES LIKE 'autocommit';

(3)把系统变量autocommit 的值设置为 OFF ,则会关闭自动提交。

SET autocommit = OFF;
#或
SET autocommit = 0;

在这里插入图片描述

(4)再次执行DML语句,发现不会自动提交。

insert into account values(null,'zs',1000);

在这里插入图片描述

(5)此时必须显示的提交事物才能生效

commit;

在这里插入图片描述

六、事务的隔离级别

1、理论

MySQL 中事务的隔离级别一共分为四种,分别如下:

  • 序列化(SERIALIZABLE)
  • 可重复读(REPEATABLE READ)
  • 提交读(READ COMMITTED)
  • 未提交读(READ UNCOMMITTED)
时刻事务1事务2
T0读取商品初始库存为2
T1扣减库存,库存为1
T2读取商品库存为1
T3回滚事务,库存为2
T4扣减库存,提交事务
T5查询库存为1

在MySQL数据库中,默认的事务隔离级别是REPEATABLE READ 可重复读

2、查看事务的隔离级别

通过如下 SQL 可以查看数据库实例默认的全局隔离级别和当前 session 的隔离级别。

(1)MySQL8 之前使用如下命令查看 MySQL 隔离级别:

SELECT @@GLOBAL.tx\_isolation, @@tx\_isolation;

(2)MySQL8 开始,通过如下命令查看 MySQL 默认隔离级别

SELECT @@GLOBAL.transaction\_isolation, @@transaction\_isolation;

在这里插入图片描述

(3)通过如下命令可以修改隔离级别(建议修改当前 session 隔离级别即可,不用修改全局的隔离级别):

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

上面这条 SQL 表示将当前 session 的数据库隔离级别设置为 READ UNCOMMITTED,设置成功后,再次查询隔离级别,发现当前 session 的隔离级别已经变了。

在这里插入图片描述

注意,如果只是修改了当前 session 的隔离级别,则换一个 session 之后,隔离级别又会恢复到默认的隔离级别,所以我们测试时,修改当前 session 的隔离级别即可。

七、READ UNCOMMITTED 未提交读

该事物隔离级别会导致出现脏读、不可重复读、幻读。

1、准备测试数据

DROP TABLE account;
create table account(
    id int primary key auto\_increment,
    name varchar(20) unique not null,
    balance int
);

insert into account values(null,'zs',1000);
insert into account values(null,'lisi',1);

在这里插入图片描述

2、脏读

一个事务读到另外一个事务还没有提交的数据,称之为脏读。具体操作如下

会话A

START TRANSACTION;
UPDATE account set balance = balance -1 WHERE name = 'lisi'

会话B

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT @@GLOBAL.transaction\_isolation, @@transaction\_isolation;

SELECT \* FROM account

在这里插入图片描述

可以看到,A 窗口中的事务,虽然还未提交,但是 B 窗口中已经可以查询到数据的相关变化了。

这就是脏读问题。

3、不可重复读

不可重复读是指一个事务先后读取同一条记录,但两次读取的数据结果不同,称之为不可重复读。

在这里插入图片描述

-- 会话A
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
START TRANSACTION;
SELECT \* FROM account WHERE name ='lisi';
SELECT SLEEP(10);
SELECT \* FROM account WHERE name ='lisi';
COMMIT;

-- 会话B
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

START TRANSACTION;
UPDATE account SET balance =  balance -500 WHERE name ='lisi';
COMMIT;


lisi的账户已经发生了变化,即前后两次查看 lisi账户,结果不一致,这就是不可重复读

和脏读的区别在于,脏读是看到了其他事务未提交的数据,而不可重复读是看到了其他事务已经提交的数据

(由于当前 SQL 也是在事务中,因此有可能并不想看到其他事务已经提交的数据)。

4、幻读

是指当事务不是独立执行时发生的一种现象。

幻象读和不可重复读非常像,看名字就是产生幻觉了。

在这里插入图片描述

-- 会话A
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
START TRANSACTION;
SELECT \* FROM account;
SELECT SLEEP(10);
SELECT \* FROM account;
COMMIT;

-- 会话B
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

START TRANSACTION;
insert into account values(null,'wangwu',1);
COMMIT;

幻读

  • 幻读说的是存不存在的问题:原来不存在的,现在存在了,则是幻读
  • 不可重复读说的是变没变化的问题:原来是A,现在却变为了B,则为不可重复读

八、 READ COMMITTED 提交读

和 READ UNCOMMITTED 相比,READ COMMITTED 主要解决了脏读的问题,对于不可重复读和幻象读则未解决。

将事务的隔离级别改为 READ COMMITTED 之后,重复上面关于脏读案例的测试,发现已经不存在脏读问题了;重复上面关于不可重复读案例的测试,发现不可重复读问题依然存在。

1、脏读测试–解决

在这里插入图片描述

-- 会话A
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION;
UPDATE account set balance = balance -1 WHERE name = 'lisi'

-- 会话B
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
SELECT @@GLOBAL.transaction\_isolation, @@transaction\_isolation;

SELECT \* FROM account

2、不可重复度和幻读–未解决

九、REPEATABLE READ 可重复读【默认】

和 READ COMMITTED 相比,REPEATABLE READ 进一步解决了不可重复读的问题,但是幻象读则未解决。

1、不可重复读测试–解决

在这里插入图片描述

-- 会话A
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION;
SELECT \* FROM account WHERE name ='lisi';
SELECT SLEEP(10);
SELECT \* FROM account WHERE name ='lisi';
COMMIT;

最后

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

isi’;
SELECT SLEEP(10);
SELECT * FROM account WHERE name =‘lisi’;
COMMIT;



# 最后

[外链图片转存中...(img-4MaHeD4z-1715460078588)]

[外链图片转存中...(img-l4yiY28d-1715460078588)]

[外链图片转存中...(img-w0E4X4Nz-1715460078589)]

> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)收录**

**[需要这份系统化的资料的朋友,可以点击这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**

  • 23
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值