Mysql事务隔离级别

导读:本篇文章讲解 Mysql事务隔离级别,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

Mysql事务隔离级别

一、数据并发问题

在了解Mysql事务隔离级别之前,先看一下访问相同数据的事务在不保证串行执行(也
就是执行完一个再执行另一个)的情况下可能会出现哪些问题:

1. 脏写( Dirty Write )
对于两个事务 Session A、Session B,如果事务Session A 修改了 另一个 未提交 事务Session B 修改过 的数据,那就意味着发生了 脏写 ,以下例子帮助理解:

发生时间 Session A Session B
BEGIN;
BEGIN;
UPDATE student SET name=‘李四’ where stuno = 1
UPDATE student SET name=‘张三’ where stuno = 1
COMMIT;
ROLLBACK;

2. 脏读( Dirty Read )
对于两个事务 Session A、Session B,Session A 读取 了已经被 Session B 更新 但还 没有被提交 的字段。之后若 Session B 回滚 ,Session A 读取 的内容就是 临时且无效 的,以下例子帮助理解:

发生时间 Session A Session B
BEGIN;
BEGIN;
UPDATE student SET name=‘张三’ where stuno = 1
SELECT * FROM student WHERE stuno = 1;(若此时读到张三,则意味着发生了‘脏读’)
COMMIT;
ROLLBACK;

Session A和Session B各开启了一个事务,Session B中的事务先将stuno列为1的记录的name列更新为’张三’,然后Session A中的事务再去查询这条stuno为1的记录,如果读到列name的值为’张三’,而Session B中的事务稍后进行了回滚,那么Session A中的事务相当于读到了一个不存在的数据,这种现象就称之为 脏读

3. 不可重复读( Non-Repeatable Read )
对于两个事务Session A、Session B,Session A 读取 了一个字段,然后 Session B 更新 了该字段。 之后Session A 再次读取 同一个字段, 值就不同了。那就意味着发生了不可重复读。

发生时间 Session A Session B
BEGIN;
SELECT * FROM student WHERE stuno = 1; (此时读到的列的值为‘王五’)
UPDATE student SET name=‘张三’ where stuno = 1
SELECT * FROM student WHERE stuno = 1;(若此时读到‘张三’,则意味着发生了‘不可重复读’)
UPDATE student SET name=‘李四’ where stuno = 1
SELECT * FROM student WHERE stuno = 1;(若此时读到‘李四’,则意味着发生了‘不可重复读’)

我们在Session B中提交了几个 隐式事务 (注意是隐式事务,意味着语句结束事务就提交了),这些事务都修改了stuno列为1的记录的列name的值,每次事务提交之后,如果Session A中的事务都可以查看到最新的值,这种现象也被称之为 不可重复读

4. 幻读( Phantom )
对于两个事务Session A、Session B, Session A 从一个表中 读取 了一个字段, 然后 Session B 在该表中 插 入 了一些新的行。 之后, 如果 Session A 再次读取 同一个表, 就会多出几行。那就意味着发生了幻读。

发生时间 Session A Session B
BEGIN;
SELECT * FROM student WHERE stuno > 0; (此时读到的列的值为‘张三’)
INSERT INTO student VALUES(2, ‘赵六’,’2班‘)
SELECT * FROM student WHERE stuno > 0;(若此时读到‘张三’和‘赵六’,则意味着发生了‘幻读’)

Session A中的事务先根据条件 stuno > 0这个条件查询表student,得到了name列值为’张三’的记录;之后Session B中提交了一个 隐式事务 ,该事务向表student中插入了一条新记录;之后Session A中的事务再根据相同的条件 stuno > 0查询表student,得到的结果集中包含Session B中的事务新插入的那条记录,这种现象也被称之为 幻读 。我们把新插入的那些记录称之为 幻影记录

二、sql隔离级别

上面四种问题按照严重性排序如下:

脏写 > 脏读 > 不可重复读 > 幻读

设立一些隔离级别可以帮助我们避免这些问题,隔离级别越低,并发问题发生的就越多。相反的,隔离级别越高,并发的性能也就越差。 SQL标准 中设立了4个 隔离级别

  • READ UNCOMMITTED :读未提交,在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。不能避免脏读、不可重复读、幻读

  • READ COMMITTED :读已提交,它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。可以避免脏读,但不可重复读、幻读问题仍然存在。

  • REPEATABLE READ :可重复读,事务A在读到一条数据之后,此时事务B对该数据进行了修改并提交,那么事务A再读该数据,读到的还是原来的内容。可以避免脏读、不可重复读,但幻读问题仍然存在。这是MySQL的默认隔离级别

  • SERIALIZABLE :可串行化,确保事务可以从一个表中读取相同的行。在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作。所有的并发问题都可以避免,但性能十分低下。能避免脏读、不可重复读和幻读
    图示如下:
    在这里插入图片描述

表格中无脏写,因为无论哪种隔离级别都不会允许脏写的出现,即都能避免脏写。
刚才也说到了隔离级别越高,并发的性能越差,4种事务隔离级别与并发性能的关系如下:
在这里插入隔离图片描述
因此一般为了兼顾并发性能我们都是选择第二种或者第三种隔离级别,即 READ COMMITTED 或者 REPEATABLE READ,且Mysql默认隔离级别就是 REPEATABLE READ

三、Mysql支持的四种隔离级别

1.查看隔离级别

# 查看隔离级别,MySQL 5.7.20的版本之前: 
mysql> SHOW VARIABLES LIKE 'tx_isolation'; 
+---------------+-----------------+
| Variable_name | Value           | 
+---------------+-----------------+
| tx_isolation | REPEATABLE-READ  | 
+---------------+-----------------+
1 row in set (0.00 sec)

# MySQL 5.7.20版本之后,引入transaction_isolation来替换tx_isolation

# 查看隔离级别,MySQL 5.7.20的版本及之后
mysql> show variables like 'transaction_isolation';
+-----------------------+-----------------+
| Variable_name         | Value           |
+-----------------------+-----------------+
| transaction_isolation | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set, 1 warning (0.06 sec)

#或者不同MySQL版本中都可以使用的: 
SELECT @@transaction_isolation;

2.设置事务的隔离级别

# 方式一
SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL ‘隔离级别’;

# 方式二
SET [GLOBAL|SESSION] TRANSACTION_ISOLATION = '隔离级别'

#隔离级别参数选项:

> READ UNCOMMITTED 
> READ COMMITTED 
> REPEATABLE READ 
> SERIALIZABLE

3.设置时使用GLOBAL或SESSION的影响

  • 使用 GLOBAL 关键字(在全局范围影响):

    • 当前已经存在的会话无效
    • 只对执行完该语句之后产生的会话起作用
  • 使用 SESSION 关键字(在会话范围影响):

    • 对当前会话的所有后续的事务有效
    • 如果在事务之间执行,则对后续的事务有效
    • 该语句可以在已经开启的事务中间执行,但不会影响当前正在执行的事务

小结:
数据库规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性
就越好,但并发性越弱。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/118513.html

(0)
seven_的头像seven_bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!