MySQL INNODB事务隔离级别——初级
事务概述
什么是事务?
- 事务时数据库操作的最小逻辑单元
- 事务可以由一个SQL组成也可以由多个SQL组成
- 组成事务的SQL要么全执行成功,要么全执行失败
开启事务:
START TRANSACTION / BEGIN
SELECT...
UPDATE...
INSERT...
COMMIT / ROLLBACK
事务的特性
特征 | 说明 |
---|---|
原子性(A) | 一个事务的所有操作,要么全部完成,要么全部不完成,不会结束在中间某一个环节。 |
一致性© | 在事务开始之前和事务结束之后,数据库的完整性没有被破坏。 |
隔离性(I) | 事务的隔离性要求每一个读写事务的对象与其他事务的操作对象能相互分离,即该事务提交前对其他事务都不可见。 |
持久性(D) | 事务一旦提交了,其结果就是永久的,就算发生了宕机等事故,数据库也能将数据恢复。 |
数据库的隔离性目的就是为了解决并发带来的问题。
并发带来的问题
脏读
- 一个事务读取了另一个事务未提交的数据
不可重复读
- 一个事务前后两次读取的同一数据不一致。
幻读
- 指一个事务两次查询的结果集记录数不一致
幻读是不可重复读的一种特殊形式
事务的隔离性
INNODB的隔离级别
隔离级别 | 脏读 | 不可重复读 | 幻读 | 隔离性 | 并发性 |
---|---|---|---|---|---|
顺序读(SERIALIZABLE) | N | N | N | 最高 | 最低 |
可重复读(REPEATABLE READ) | N | N | N |
||
读已提交(READ COMMITTED) | N | Y | Y | ||
读未提交(READ UNCOMMITTED) | Y | Y | Y | 最低 | 最高 |
设置事务的隔离级别:
SET SESSION / GLOBAL
TRANSACTION ISOLATION LEVEL
{
READ UNCOMMITTED
READ COMMITTED
REPEATABLE READ
SERIALIZABLE
}
隔离级别演示
顺序读(SERIALIZABLE)——串行化
# TRANSACTION 1
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SHOW VARIABLES LIKE '%iso%';
BEGIN;
SELECT course_id ,title
FROM imc_course
WHERE score>9.6;
#TRANSACTION 2
BEGIN;
UPDATE imc_course
SET score = 9.8
WHERE course_id = 34;
结果你会发现在在事务1未提交的情况下,事务2处于无限执行状态(阻塞状态)。
只有等事务1提交或者回滚后,事务2才能执行成功。
这就是事务的串行化,在这个隔离级别下,事务是不存在并发的。
可重复度(REPEATABLE READ)
# TRANSACTION 1
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SHOW VARIABLES LIKE '%iso%';
BEGIN;
SELECT course_id ,title
FROM imc_course
WHERE score>9.6;
#TRANSACTION 2
BEGIN;
UPDATE imc_course
SET score = 9.8
WHERE course_id = 30;
COMMIT;
事务1未提交,事务2提交后,查询语句的结果还是原来的结果。不会出现不可重复读或者幻读。
读已提交(READ COMMITTED)
# TRANSACTION 1
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
SHOW VARIABLES LIKE '%iso%';
BEGIN;
SELECT course_id ,title
FROM imc_course
WHERE score>9.6;
#TRANSACTION 2
BEGIN;
UPDATE imc_course
SET score = 9.8
WHERE course_id = 30;
COMMIT;
事务1未提交,事务2提交后,查询语句能查询到新更新的数据。会出现不可重复读以及幻读。
读未提交(READ UNCOMMITTED)
# TRANSACTION 1
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SHOW VARIABLES LIKE '%iso%';
BEGIN;
SELECT course_id ,title
FROM imc_course
WHERE score>9.6;
#TRANSACTION 2
BEGIN;
UPDATE imc_course
SET score = 9.8
WHERE course_id = 30;
COMMIT;
在事务2为提交的情况下,事务1都能查询到更新的数据。会出现脏读、不可重复读以及幻读。