MySQL----事务的隔离级别(附带每一级别实例截图)

发布于:2024-06-17 ⋅ 阅读:(14) ⋅ 点赞:(0)

先来回顾一下事务并发可能存在的三大问题:

脏读(Dirty Read)–不能接受

一个事务读取了另一个事务未提交的数据。例如当事务A和事务B并发执行时,当事务A更新后,事务B查询读取到A尚未提交的数据,此时事务A回滚,则事务B读到的数据就是无效的脏数据。(事务B读取了事务A尚未提交的数据)

不可重复读(NonRepeatable Read)—具体业务具体分析

一个事务的操作导致另一个事务前后两次读取到不同的数据。例如当事务A和事务B并发执行时,当事务B查询读取数据后,事务A更新操作更改事务B查询到的数据,此时事务B再次去读该数据,发现前后两次读的数据不一样。(事务B读取了事务A已提交的数据)

虚读(Phantom Read)幻读—具体业务具体分析

一个事务的操作导致另一个事务前后两次查询的结果数据量不同。例如当事务A和事务B并发执行时,当事务B查询读取数据后,事务A新增或者删除了一条满足事务B查询条件的记录,此时事务B再去查询,发现查询到前一次不存在的记录,或者前一次查询的一些记录不见了。(事务B读取了事务A新增加的数据或者读不到事务A删除的数据)

隔离级别

为了解决以上问题,MySQL为事务提供了四种隔离级别,由低到高分别为Read Uncommited、Read Commited、Repeatable Read、Serializable。

  • TRANSACTION_READ_UNCOMMITTED。未提交读。说明在提交前一个事务可以看到另一个事务的变化。这样读脏数据,不可重复读和虚读都是被允许的。
  • TRANSACTION_READ_COMMITTED。已提交读。说明读取未提交的数据是不允许的。这个级别仍然允许不可重复读和虚读产生。脏读不会产生
  • TRANSACTION_REPEATABLE_READ。可重复读。说明事务保证能够再次读取相同的数据而不会失败,但虚读仍然会出现。脏读和不可重复读不会产生
  • TRANSACTION_SERIALIZABLE。串行化。是最高的事务级别,它防止读脏数据,不可重复读和虚读。就是串行读取数据,隔离级别最高,但是并发性最低,比较消耗数据库性能,一般不用。

总结:

  • 四种隔离级别对以上三种并发存在的问题的解决能力:
隔离级别 脏读 不可重复读 幻读
未提交读 × × ×
已提交读 × ×
可重复读 ×
串行化
  • 越往上(->未提交读),并发能力越高,但是数据的一致性以及安全性越差;越往下(->串行化),并发能力越高,数据的一致性以及安全性越高。
  • 事务隔离级别越高,为避免冲突所花费的性能也就越多。
  • 在“可重复读”级别,实际上可以解决部分的虚读问题,但是不能防止update更新产生的虚读问题,要禁止虚读产生,还是需要设置串行化隔离级别。

查看隔离级别

select @@transaction_isolation;

设置隔离级别

set transaction_isolation='READ-UNCOMMITTED';

在这里插入图片描述

举个栗子~

READ-UNCOMMITTED 未提交读

在这里插入图片描述

READ-COMMITTED 已提交读

在这里插入图片描述

REPEATABLE_READ 可重复读—MySQL的默认隔离级别

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可重复读在一定意义上,是可以防止虚读的!他可以防止insert和delete,但是不能防止update。

SERIALIZABLE 串行化

在这里插入图片描述
相当于读写锁,允许一起读,不允许一起写。mysql不会运行一直阻塞,超过时间限制就会报错。