Mysql中事务特性、隔离级别以及案例演示

事务

1. 基本介绍

1.事务用于保证数据的一致性,它由一组相关的dml语句组成,该组语句要么全部成功,要么全部失败。
如:转账就要用事务来处理,保证数据的一致性。
例子:
在这里插入图片描述
2.事务与锁:
当执行事务操作时(dml语句),mysql会在表面加锁,防止其他用户修改表的数据。

2.事务的基本操作

在这里插入图片描述
注意
1.rollback语句,回退到事务开始的状态
2.commit语句,当执行了commit语句之后,就自动删除了保存点,就没有机会回退。
3.回退到前面的保存点(如a点)时,中间的保存点(如b点)也会被删除,不能再回退到中间的保存点。

代码演示:

-- 事务的具体操作
-- 1.建表
CREATE TABLE t27(
id INT, 
NAME VARCHAR(32));
-- 2.开启一个事务
 START TRANSACTION ;
-- 3.设置保存点
SAVEPOINT a;
-- 执行dml操作
INSERT INTO t27 VALUES(100,'tom');
SELECT *FROM t27;
SAVEPOINT b;
-- 执行dml操作
INSERT INTO t27 VALUES(200,'jack');
-- 回退到b
ROLLBACK TO b;

-- 回退到a;
ROLLBACK ;

插入两条语句后查询结果:
在这里插入图片描述
回退到b查询的结果:
在这里插入图片描述
全部回退查询到的结果:
在这里插入图片描述

3.事务的注意事项

在这里插入图片描述
1.不开始事务,默认执行完语句后有一个commit语句,自动提交;
5.mysql事务机制需要innodb地存储引擎才能使用,myisam不行。
InnoDB 存储引擎支持事务,MyISAM不支持。
6.开始一个事务的另一种方式:
set autocommit = off;

4.事务的隔离级别

在这里插入图片描述
含义:在不同的事务中根据事务的隔离级别不同,每一个事务看到同一个表的数据不同。

4.1无事务隔离导致的问题

4.1.1脏读

脏读: 当一个事务读取另一个事务尚未提交的改变(update、insert、delete)时,产生脏读。
(即:读到另一个事务做的修改的数据,但是此事务可能并不会提交或者会回滚,这个数据称为脏读。)

4.1.2不可重复读

不可重复读: 同一查询在同一个事务中多次进行,由于其他提交事务所做的修改或删除,导致的每次返回不同的结果,此时发生不可重复读。

4.1.3幻读

幻读: 同一查询在同一事务中多次进行,由于其他事务所做的插入操作,每次返回不同的结果集,此时发生幻读。
(即:再次进行select语句时,所查询到的结果中多了一条语句)

4.1.4三者的区别

脏读: 指读到了其他事务未提交的数据.
不可重复读: 读到了其他事务已提交的数据(update).

不可重复读与幻读都是读到其他事务已提交的数据,但是它们针对点不同.

不可重复读: delete,update.
幻读: insert.
在这里插入图片描述

4.2事务隔离的案例

注意
mysql事务默认级别为: 重复读
以下实验:所有的插入、更新等操作都是在可重复读级别事务中进行,通过对另一个事务级别进行调整,看另一个事务不同级别情况下,所得到的数据,是否存在脏读、不可重复读、幻读的问题。

4.2.1.在读未提交级别下案例演示

代码演示:

-- 演示mysql的事务隔离级别

-- 1.开启两个MySQL的控制台
-- 2.查看当前mysql的隔离级别

SELECT @@tx_isolation;

-- mysql> SELECT @@tx_isolation;
-- ERROR 1193 (HY000): Unknown system variable
-- 'tx_isolation'
-- mysql8中使用一下语句
-- mysql> SELECT @@transaction_isolation;
-- +-------------------------+
-- | @@transaction_isolation |
-- +-------------------------+
-- | REPEATABLE-READ         | **mysql默认级别**
-- +-------------------------+
-- 1 row in set (0.00 sec)

-- 3.将其中一个隔离级别设置成 Read uncommitted
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
-- 4.启动两个事务
-- 5.建表
CREATE TABLE account(
id INT ,
NAME VARCHAR(32),
money INT );
-- 6.插入一条语句在RR级别事务中,之后在两个事务中查询,
-- 都得到数据,此时发生脏读(事务未提交)
........后续得到不可重复读,幻读,看图可知

两个事务都未提交时进行插入操作
在这里插入图片描述
此时在读未提交事务中查询到插入语句,即造成的脏读
在这里插入图片描述
在可重复读级别事务中进行更新以及插入操作并提交
在这里插入图片描述
在读未提交事务中都查询到了更新、插入的结果,即造成的不可重复读、脏读
在这里插入图片描述
解读:开启两个事务,连接到数据表时,每个事务看到的数据都应该是开启事务时表的数据,而不是随时受其他事务影响的数据。

4.2.2 读已提交级别案例演示

1.提交另一个未提交的事务,并在一边开启一个新的事务。
2.在起初设置为 READ-UNCOMMITTED级别的事务中,将其级别设置为REPEATABLE-READ(mysql默认级别),并开启事务。
3.在可重复读级别事务插入一条数据,并查看;
在这里插入图片描述
此时在未进行插入操作(读已提交级别)事务中查询不到数据。
说明此时读已提交级别,不可出现脏读

4.在事务中进行update语句,并提交
在这里插入图片描述
此时另一个事务中查询到插入的语句以及更新的语句,出现了不可重复读、幻读

4.2.3 可重复读级别案例演示

1.设置一个事务级别为可重复读(Repeatable read)
2.为避免出错,可再次提交事务并开启事务(两个)
3.在其中一个事务中插入并更新数据,查询两表。

如图:未提交时没有变化
在这里插入图片描述
提交后,任未出现变化,可重复读级别解决了三个问题
在这里插入图片描述

4.2.4 可串行化级别案例演示

1.将其中一个事务设置为可串行化级别(Serializable)
在另一个事务(可重复读级别)中插入数据后
2.在查看新插入的一行数据时,可串行化级别的表出现等待。
在这里插入图片描述
3.查询全表时也出现,可串行化级别的表也超时等待;
在这里插入图片描述
4.执行insert语句可串行化的表未出现等待:
在这里插入图片描述
提交事务后查出,在此之前出现了超时现象
在这里插入图片描述
重点解读
1、mysql的可串行化
首先:可串行化serializable这是事务的最高级别,会加上锁,使之不可能相互冲突,因此,会导致大量的超时现象。(当它发现一个表在被一个事务操作且未提交,它会阻塞)
可串行化的锁机制:
在A、B客户端都开启事务;
1.如果A事务删除某条记录(尚未提交回滚),B事务无法读取A事务中删除且未提交的事务,这是因为A事务中加了写锁
2.如果A事务插入了一条数据(假如ID为4),那么B事务中,ID = 1、2、3都可以正常读,但是 select * from account where id = 4; 就会等待
原因:

4.3设置隔离级别

在这里插入图片描述
补充:
若需要修改默认隔离级别,不必每次修改,可进行全局修改。
在这里插入图片描述

5.事务的ACID特性

在这里插入图片描述
解读:
2.一致性:事务作为整体提交之后就结束了,然后开启新的事务,所以具有一致性。

6.JDBC中事务的特性

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值