回滚
BEGIN;
delete from account where name='zs';
ROLLBACK
保存点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 可重复读【默认】
文末
我将这三次阿里面试的题目全部分专题整理出来,并附带上详细的答案解析,生成了一份PDF文档
- 第一个要分享给大家的就是算法和数据结构
- 第二个就是数据库的高频知识点与性能优化
- 第三个则是并发编程(72个知识点学习)
- 最后一个是各大JAVA架构专题的面试点+解析+我的一些学习的书籍资料
还有更多的Redis、MySQL、JVM、Kafka、微服务、Spring全家桶等学习笔记这里就不一一列举出来
】
文末
我将这三次阿里面试的题目全部分专题整理出来,并附带上详细的答案解析,生成了一份PDF文档
- 第一个要分享给大家的就是算法和数据结构
[外链图片转存中…(img-5VfNnoFS-1714428732607)]
- 第二个就是数据库的高频知识点与性能优化
[外链图片转存中…(img-tny6JLaQ-1714428732607)]
- 第三个则是并发编程(72个知识点学习)
[外链图片转存中…(img-e6baJ6je-1714428732608)]
- 最后一个是各大JAVA架构专题的面试点+解析+我的一些学习的书籍资料
[外链图片转存中…(img-Mmlapgb3-1714428732608)]
还有更多的Redis、MySQL、JVM、Kafka、微服务、Spring全家桶等学习笔记这里就不一一列举出来