这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战
前言:
本篇文章是我关于MySQL的第七篇文章,水平一般、能力有限。文章写的比较浅,适合新手来看。上一篇文章讲到了事务的由来,本篇介绍事务的隔离级别。
隔离级别介绍
前文中讲MySQL的隔离性时说到,一般情况下事务在未完成时对其他连接是不可见的。但是只是一般情况下,SQL标准中规定了四种隔离级别,每种隔离级别的允许事务间的可见级别是不同的。(每中存储引擎实现的隔离级别也略有不同)
隔离级别越低,可以执行的并发也就越高,性能也就越高。反之,隔离级别越高,执行的并发会低,性能也会低。
查询当前隔离级别
-- 这两种都可以(默认查询的是会话级别,查询系统级别为 global.transaction_isolation
mysql> select @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| REPEATABLE-READ |
+-------------------------+
mysql> show variables like 'transaction_isolation';
+-----------------------+-----------------+
| Variable_name | Value |
+-----------------------+-----------------+
| transaction_isolation | REPEATABLE-READ |
+-----------------------+-----------------+
mysql 8.0之前用
show variables like 'tx_isolation';
修改隔离级别
set session transaction isolation level REPEATABLE READ;
set session transaction isolation level READ COMMITTED;
set session transaction isolation level REPEATABLE READ;
set session transaction isolation level SERIALIZABLE;
下面我们来实际体验一下,首先建表和造数据。
CREATE table xuezhong_role (
name char(4) not null comment '角色名称',
remark varchar(20) not null comment '评语',
power smallint NOT NULL COMMENT '武力值'
) ENGINE=InnoDB;
select * from xuezhong_role;
name|remark |power|
----+---------------+-----+
曹长卿 |天下风流一石,曹长卿独占八斗 | 88|
李淳罡 |天不生我李淳罡,剑道万古如长夜| 95|
1.READ UNCOMMITTED(读未提交)
顾名思义就是可以读取到正在执行中,但是还没提交的事务,这也被称之为脏读(Dirty Read)。如果一个连接正在修改的数据还未提交就被读取到是很危险的。并且在性能上并没有提升太多。一般在开发应用场景中用不到。
会话1: 关闭自动提交,开启事务,执行更新。此时事务还未被提交
SET AUTOCOMMIT=0 ;
start transaction;
update xuezhong_role set power=100 where name ='曹长卿';
会话2:修改隔离级别,直接查询。此时查询到了另一个会话中未提交的事务数据。
set session transaction isolation level REPEATABLE READ;
select * from xuezhong_role where name ='曹长卿';
+-----------+--------------------------------------------+-------+
| name | remark | power |
+-----------+--------------------------------------------+-------+
| 曹长卿 | 天下风流一石,曹长卿独占八斗 | 100 |
+-----------+--------------------------------------------+-------+
会话1: 回滚数据
rollback;
会话2:再次查询,数据恢复为88
select * from xuezhong_role where name ='曹长卿';
+-----------+--------------------------------------------+-------+
| name | remark | power |
+-----------+--------------------------------------------+-------+
| 曹长卿 | 天下风流一石,曹长卿独占八斗 | 88 |
+-----------+--------------------------------------------+-------+
2. READ COMMITTED(读已提交)
顾名思义就是只能读取到已经执行完的事务,这也是大部分数据库采用的事务隔离级别,例如Oracle。但是MySQL采用的不是这种隔离级别。这种隔离级别又被称之为不可重复读。
3. REPEATABLE READ(可重复读)
MySQL采用的默认级别,执行事务前和后得到的查询结果是一致的。
4. SERIALIZABLE(可串行化)
一般较少采用的隔离级别。