MySQL事务隔离级别

前言

  我们在上一篇  《MySQL之初识事务》中介绍了事务的基本概念,以及查看当前事务属性,如何手动开启,提交,回滚事务。事务中还有一个非常重要的概念—-事务隔离级别。今天就一起来看看事务的隔离级别!

什么是隔离级别?

官方文档中这么描述:

The isolation level is the setting that fine-tunes the balance between performance and reliability, consistency, and reproducibility of results when multiple transactions are making changes and performing queries at the same tim

  隔离级别是在多个事务同时进行更改和执行查询时,对结果的性能和可靠性,一致性和可重复性之间的平衡进行微调的设置。
也就是说,数据一致性与性能和可靠性成反比,我们根据业务需求,来选择合适的隔离级别。所有脱离业务需求,来选择隔离级别的都是耍流氓!!!

隔离级别

  在MySQL InnoDB引擎中提供了SQL标准中定义的所有四个隔离级别,分别是:
READ UNCOMMITTED(未提交读)。
READ COMMITTED(提交读)。
REPEATABLE READ(可重复读)。
SERIALIZABLE(可串行化)。

下面分别介绍这四类隔离级别的作用,以及场景。

READ UNCOMMITTED(未提交读)

  还记得上一篇文章,我们说 begin; 只是开启事务,没有commit提交的话,是没有真正提交的。没有持久化的对不对。相应的其它事务也读取不到未提交的值对不对,但如果我们将隔离级别设置为READ UNCOMMITTED的话,那就会获取到未提交的数据哦。
例如:

原始数据

1
INSERT INTO `andyqian`.`t_base_user` (`oid`, `name`, `email`, `age`, `telephone`, `status`, `created_at`, `updated_at`) VALUES ('3866584', 'andyqian', 'andytohome@gmail.com', '1', '12345678901', '1', '2017-11-21 21:15:04', '2017-11-21 21:1:40');

事务A:

1
2
begin;
update t_base_user set email="11111111@gmail.com",updated_at=now() where oid=3866584;

注意此时事务Ab并没有commit。

我们再开启一个事务B;

1
2
3
4
5
begin;

select * from t_base_user where email=”11111111@gmail.com";

commit;

这个时候,其实事务B已经查询出来了, 11111111@gmail.com已经是事务A未提交的数据对不对。(为了方便试验,可以将自动提交禁用掉。set autocommit=0);

  细心的童鞋应该发现问题了,假如事务A这个语句写错了,不commit,或rollback(回滚)后,但事务B已经读取了事务A未commit的数据,这时候就造成了数据不一致的问题,产生脏读! 所以,该隔离级别一般很少使用。

READ COMMITTED(提交读)

  顾名思义,也就是说: 事务只能查看到已经提交后的事务,持久化后的数据,换句话说: 未提交的事务,所进行的修改,均不会被读取到,这也是大多数数据库系统的默认事务级别。(MySQL默认的隔离级别是:可重复读)。

REPEATABLE TABLE(可重复读)

  这是MySQL默认的事务隔离级别,保证了在同一个事务中多次读取记录的结果是一致的。也解决了READ UNCOMMITITED(未提交读)中的脏读问题。

SERIALIZABLE(可串行化)

  该隔离级别是最高的隔离级别,保持了数据的强一致性,但有利也有弊,该隔离级别是通过强制事务串行执行,就像队列一样,一个紧接着一个,在大并发应用时,就会导致大量的超时和锁竞争产生。所以在平时,一般情况下也很少使用该事务隔离级别。

查看&修改事务隔离级别

  我们可以下面命令查看会话隔离级别,以及全局隔离级别。
当前会话隔离级别:

1
select @@tx_isolation

会话隔离级别图片
全局隔离级别:

1
select @@global.tx_isolation;

全局隔离级别图片
同样,我们也可以修改默认的隔离级别,通过如下命令:
修改当前会话隔离级别:

1
set session transaction isolation level read uncommitted;

修改全局隔离级别:

1
set global transaction isolation level read uncommitted;

这里值得注意的是,如果生产环境, 不要轻易修改事务的隔离级别(除非有特别特殊理由,否则最好别修改)。
例如: 从(REPEATABLE READ(可重复读))修改为(SERIALIZABLE(可串行化),就存在很大的风险,会导致大量的超时,导致性能急速下降,影响业务使用。

也就是说:事务的隔离级别,在数据库前期就应该根据业务方式,来确定好。后续就不应该进行修改。

今日命令

  今天介绍的命令,在查看服务器连接,排查连接过多,查看连接状态时特别有用!

命令: show full processlist

作用: 显示当前运行的线程以及状态,也可以根据该命令来查看服务器状态。

插入processlist图片

Id: 连接Id。
User: 操作用户名,这里的用户是MySQL中的用户
Host: 顾名思义,这里显示的是客户端用户的Host名以及端口号。这里需要注意的是系统用户并不显示。
db: 客户端连接的数据库,这里的andyqian就是数据库名称。
Command: 表示客户端正在执行的命令类型,这里的类型有:Sleep,Query(查询),Binlog Dump(在主从复制时常见), Change user(线程正在更改用户)等。一般通过该属性也能看出当前进程的状态。
此属性状态还有很多,下次单独写一篇文章拎出来说说。

Time: 指当前连接处于该状态的时间。(单位:秒)
State: 指当连接正在执行的动作,事件或状态。使用show processlist命令时,一般为null值。
Info: 当前连接正在执行的语句,如果没有执行任何语句,则为Null。


相关阅读:

写会MySQL索引

读懂MySQL执行计划

谈谈MySQL隐式类型转换

学会MySQL LIMIT


这里写图片描述

扫码关注,一起进步

个人博客: http://www.andyqian.com