索码理

V1

2022/07/13阅读:28主题:全栈蓝

温故而知新-MySQL隔离级别

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。

要了解隔离级别,首先要了解一下事务,隔离级别只有在事务操作下才起作用。

事务

事务是由一组SQL语句组成的逻辑处理单元,这些操作要么全部执行成功,要么全部失败。

事务特性

  • 原子性(Atomicity):事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行。

  • 一致性(Consistency):在事务开始和完成时,数据都必须保持一致状态。这意味着所有相关的数据规则都必须应用于事务的修改,以保持数据的完整性。

  • 隔离性(Isolation):数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独立”环境执行。这意味着事务处理过程中的中间状态对外部是不可见的,反之亦然。

  • 持久性(Durability):事务完成之后,它对于数据的修改是永久性的,即使出现系统故障也能够保持。

并发事务处理带来的问题

  • 更新丢失(脏写):多个事务对同一条记录进行修改时,最后的操作覆盖了之前的事务操作,结果前面的操作更新丢失了。这种现象称之为更新丢失

  • 脏读:一个事务正在对一条记录进行修改,并未提交,在未加锁时另一个事务在读取到了该未提交的记录并对该记录又进行了操作,就造成了数据前后不一致的情况。这种现象称为脏读
    你一个朋友在给你转账一万元,转账事务还没结束,你去查看账户余额发现已经多了一万,这个时候读取到账户余额多出一万的情况就是脏读。如果你把这笔钱花了,而这个事务也回滚了,就会出现数据不一致的情况。

  • 幻读:一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象称为幻读
    查看完账户余额,你又去这个月查看账单,此时你在查看账单这个事务中。第一次查看的时候看到这个月只有一笔收入,莫名其妙你又查看了一下这个月账单发现多出一条一百万的收入,多出的一条一百万的记录就是幻读。

  • 不可重读:一个事务在读取某些数据后的某个时间,再次读取以前读过的数据,却发现其读出的数据已经发生了改变或某些记录已经被删除了。这种现象称为不可重复读
    你去查看这个一百万账单的详情,此时你在查看账单详情的事务中,也不知道哪个老几给你转的。此时那个老几发现转账错误,就给银行打电话取消这笔转账。与此同时你想去查看更多关于这笔账单的信息时,结果提示你没有这笔账单,银行方面撤回了。在查看账单详情的事务中读取同一条记录得到不同结果的情况就是不可重复读。

更新丢失是写的问题,脏读、幻读、不可重复读是读的问题。

隔离级别

隔离级别是在多个事务同时进行更改和执行查询时,微调性能与结果的可靠性、一致性和再现性之间的平衡的设置。

隔离级别一致性和保护性从低到高依次为:

  • 读未提交(Read Uncommitted)
  • 读已提交(Read committed)
  • 可重复读(Repeatable Read)
  • 串行化(SERIALIZABLE)

读未提交(Read Uncommitted)

读未提交就是一个事务对数据进行了修改,但是并未提交,其他事务可以读到这个未提交的数据,这个时候就会出现脏读。该级别很少会被使用。

读未提交 事务B读取到事务A未提交的数据,这造成了脏读。

读已提交(Read committed)

一个事务读取到其他事务修改过并且已经提交的的数据,每当其他事务提交修改过的数据时,都能被当前事务读取到。读已提交解决了脏读问题,可能会出现幻读、不可重复读。

读已提交 事务A提交之后,事务B才能查到a的值

可重复读(Repeatable Read)

MySQL InnoDB引擎的默认隔离级别。事务T1在第一次读取到某条记录时,即使有其他事务对该记录进行了修改,事务T1读到的仍然是第一次读取到的记录,而不是每次都读取到不同的值,这就是可重复读。可重复读解决了脏读、不可重复读,还是会出现幻读,MySQL通过MVCC(多版本并发控制)在一定程度上解决了幻读问题,有关MVCC下篇文章会介绍。

可重复读在同一个事务第一次查询的时候会生成一个快照,当在这个事务中再次以相同条件查询时,查询到的数据其实是快照中的数据,以此来达到可重复读。

可重复读 事务A和事务B都能获取到a=1,事务A将a的值修改为2,然后提交事务,这时虽然a的值在数据库中已经是2了,但是事务B在未提交之前获取到的a仍然是1,这就是可重复读。

串行化(SERIALIZABLE)

最高的隔离级别,它强制事务串行执行。实际中很少用到,只有在非常需要确保数据的一致性而且可以接受没有并发的情况下,才考虑。 串行化事务执行的时候不允许别的事务并发执行.完全串行化的读,只要存在读就禁止写,但可以同时读,消除了幻读。

事务隔离级别越高,数据的完整性和一致性也越高,但是并发度越小,对系统的访问速度影响也越大。不同应用对事务的隔离级别要求可能不一样,如果应用对幻读不敏感的话,就是用当前MySQL默认的隔离级别即可。

查看隔离级别

1、查看系统隔离级别

show variables like 'transaction_isolation';

或者

select @@global.tx_isolation;

2、查看会话隔离级别

select @@tx_isolation;

设置隔离级别

1、 全局隔离级别设置

set global transaction isolation level 隔离级别;

-- 设置隔离级别为可重复读
set global transaction isolation level REPEATABLE READ;

2、会话隔离级别设置

set session transaction isolation level 隔离级别;

set session transaction isolation level REPEATABLE READ;

能力一般,水平有限,如有错误,请多指出。
如果文章对你有用点个关注给个赞呗
更多文章可以关注一下我的微信公众号suncodernote

分类:

后端

标签:

数据库

作者介绍

索码理
V1