Skip to content

Instantly share code, notes, and snippets.

@bllli
Last active November 15, 2017 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bllli/6be0cf7cdd975332cd2ba7967439efb4 to your computer and use it in GitHub Desktop.
Save bllli/6be0cf7cdd975332cd2ba7967439efb4 to your computer and use it in GitHub Desktop.
MySQL 学习记录

MySQL 事务

测试环境 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)

参考: http://www.cnblogs.com/zhoujinyi/p/3437475.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment