Mysql 隔离级别配置修改
Mysql 隔离级别配置修改
题外话
在日常的mysql管理中,一旦确定好隔离级别,很少会去修改的,但遇到特殊情况需做修改,本文介绍了mysql 四种隔离级别的含义和持久化修改方法。
一、事务的四个特征(ACID)
事务具有四个特征:原子性( Atomicity )、一致性( Consistency )、隔离性( Isolation )和持续性( Durability )。这四个特性简称为 ACID 特性。
1 、原子性。事务是数据库的逻辑工作单位,事务中包含的各操作要么都做,要么都不做
2 、一致性。事 务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。如果数据库系统 运行中发生故障,有些事务尚未完成就被迫中断,这些未完成事务对数据库所做的修改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,或者说是 不一致的状态。
3 、隔离性。一个事务的执行不能其它事务干扰。即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。
4 、持续性。也称永久性,指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。接下来的其它操作或故障不应该对其执行结果有任何影响。
二、Mysql的四种隔离级别
SQL标准定义了4类隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的。低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。
Read Uncommitted(读取未提交内容)
在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。
Read Committed(读取提交内容)
这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。
Repeatable Read(可重读)
这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。
Serializable(可串行化)
这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。
在MySQL中,实现了这四种隔离级别,分别有可能产生问题如下所示:
三、隔离级别设置修改
# 查看隔离级别
SELECT @@GLOBAL.transaction_isolation;
SELECT @@SESSION.transaction_isolation;
show variables like '%iso%';
# 设置全局隔离级别
set global transaction isolation level REPEATABLE READ;
set global transaction isolation level READ COMMITTED;
set global transaction isolation level READ UNCOMMITTED;
set global transaction isolation level SERIALIZABLE;
# 设置会话隔离级别
set session transaction isolation level REPEATABLE READ;
set session transaction isolation level READ COMMITTED;
set session transaction isolation level READ UNCOMMITTED;
set session transaction isolation level SERIALIZABLE;
#通过配置文件设置隔离级别(重启生效)
[mysqld]
transaction-isolation = REPEATABLE-READ
transaction-isolation = READ-COMMITTED
transaction-isolation = READ-UNCOMMITTED
transaction-isolation = SERIALIZABLE
实践
#查看当前隔离级别
mysql> SELECT @@GLOBAL.transaction_isolation;
+--------------------------------+
| @@GLOBAL.transaction_isolation |
+--------------------------------+
| REPEATABLE-READ |
+--------------------------------+
1 row in set (0.00 sec)
#设置个隔离级别为RC
mysql> set global transaction isolation level READ COMMITTED;
Query OK, 0 rows affected (0.00 sec)
#再次查看隔离级别,设置成功 **注意要新开会话再查看**
mysql> SELECT @@GLOBAL.transaction_isolation;
+--------------------------------+
| @@GLOBAL.transaction_isolation |
+--------------------------------+
| READ-COMMITTED |
+--------------------------------+
1 row in set (0.00 sec)
#相应隔离级别参数加入配置文件(保证重启持久化)
[mysqld]
......
transaction-isolation=Read-Committed
可以通过命令行设置全局 或 会话的隔离级别。重启或者退出会话失效
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}
具体命令
# 设置全局隔离级别 set global transaction isolation level REPEATABLE READ; set global transaction isolation level READ COMMITTED; set global transaction isolation level READ UNCOMMITTED; set global transaction isolation level SERIALIZABLE; #设置会话隔离级别 set session transaction isolation level REPEATABLE READ; set session transaction isolation level READ COMMITTED; set session transaction isolation level READ UNCOMMITTED; set session transaction isolation level SERIALIZABLE;
通过配置文件设置隔离级别
[mysqld] transaction-isolation = REPEATABLE-READ transaction-isolation = READ-COMMITTED transaction-isolation = READ-UNCOMMITTED transaction-isolation = SERIALIZABLE
查看隔离级别
SELECT @@GLOBAL.transaction_isolation SELECT @@SESSION.transaction_isolation show variables like '%iso%';
从官方文档粘贴下来的命令可能是因为格式原因执行就报错
但还是粘一下地址吧 https://dev.mysql.com/doc/refman/5.7/en/set-transaction.html
目录 返回
首页