测试环境 mysqld Ver 5.7.20-0ubuntu0.17.04.1 for Linux on x86_64 ((Ubuntu))
隔离级别 | 脏读(Dirty Read) | 不可重复读(NonRepeatble) | 幻读(Phantom Read) |
---|---|---|---|
未提交读(Read uncommitted) | 可能 | 可能 | 可能 |
已提交读(Read committed) | 不可能 | 可能 | 可能 |
可重复读(Repeatable read) | 不可能 | 不可能 | 可能 |
可串行化(Serializable) | 不可能 | 不可能 | 不可能 |
- 未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
- 提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)
- 可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读
- 串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞
命令行用--transaction-isolation
选项
选项文件 (my.inf文件的[mysqld]节里)
transaction-isolation = {READ-UNCOMMITTED | READ-COMMITTED | REPEATABLE-READ | SERIALIZABLE}
用户可以用SET TRANSACTION语句改变单个会话或者所有新进连接的隔离级别。
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}
- 不带 SESSION 和 GLOBAL 是为下一个事务设置隔离级别。
- 使用 GLOBAL 关键字,语句在全局对从那点开始创建的所有新连接设置默认事务级别,需要SUPER权限。
- 使用 SESSION 关键字为将来在当前连接上执行的事务设置默认事务级别。
- 任何客户端都能自由改变会话隔离级别(事务的中间也可以),或者为下一个事务设置隔离级别。
SELECT @@global.transaction_isolation;
SELECT @@session.transaction_isolation;
SELECT @@transaction_isolation;
-- 先创建好环境
CREATE DATABASE IF NOT EXISTS DEMO;
USE DEMO;
CREATE TABLE IF NOT EXISTS User(
id INTEGER AUTO_INCREMENT PRIMARY KEY
);
session 1
mysql> USE DEMO;
Database changed
mysql> SELECT @@global.transaction_isolation, @@session.transaction_isolation, @@transaction_isolation;
+--------------------------------+---------------------------------+-------------------------+
| @@global.transaction_isolation | @@session.transaction_isolation | @@transaction_isolation |
+--------------------------------+---------------------------------+-------------------------+
| READ-COMMITTED | REPEATABLE-READ | REPEATABLE-READ |
+--------------------------------+---------------------------------+-------------------------+
1 row in set (0.00 sec)
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * FROM User;
Empty set (0.00 sec)
mysql> INSERT INTO User VALUES (1, 'bllli');
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM User;
+----+-------+
| id | name |
+----+-------+
| 1 | bllli |
+----+-------+
1 row in set (0.00 sec)
session 2
-- 注意 此时session 1还没有提交
mysql> SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
Query OK, 0 rows affected (0.00 sec)
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * FROM User;
+----+-------+
| id | name |
+----+-------+
| 1 | bllli |
+----+-------+
1 row in set (0.00 sec)