MySQL事务隔离级别-脏读,幻读,不可重复读
概述
名词解释
共享锁(shared lock)
: 这种锁允许事务对读锁定的对象进行读取操作, 同时允许其他的事务也对这个对象施加共享锁, 但是不能对锁定的对象进行写入, 共享锁的反面是排它锁.排它锁(exclusive lock)
: 一种可以防止其他事务锁定同一行的锁, 这种锁可能会阻止其他事务写入或者读取锁定的对象, 而InnoDB使用MVCC技术来实现对呗排它锁锁定的对象读取来提高并发性.一致性读(consistent read)
: 利用快照snapshot
信息来根据某个时间点来读取数据, 而不管其他事务对该对象做了什么操作, 如果其他的事务已经完成操作, 则会通过撤销日志(undo log)来重建数据.锁定读
: 在读取的时候, 使用某种锁锁定需要读取的数据.
# 使用共享锁(Share Lock)锁定
select * from t1 lock in share mode;
# 使用排它锁(Exclusive Lock)锁定
select * from t1 where id=1 lock for update;
非锁定读:
select * from t1 where id=1;
事务相关操作语句
# 查看当前MySQL数据库版本
select version();
# 查看当前数据库的隔离级别
SELECT @@tx_isolation;
# 设置隔离级别
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL
{
READ UNCOMMITTED
| READ COMMITTED
| REPEATABLE READ
| SERIALIZABLE
}
# 开始事务
start transaction;
# begin也也是开启一个事务
begin;
# 提交事务
commit;
# 回滚事务
rollback;
脏读(Dirty Read)
:
现象
脏读
: 事务A在操作某行数据, 此时事务B开始读取数据, 然后事务A回滚事务, 此时事务B读取到的数据就是脏数据
, 而事务B这种读取到其他事务的中间数据的过程就是脏读.不可重复读
: 事务A在开启事务后,两次读取同一行, 发现返回不同的数据, 这种在一个事务中两次读取到不同数据的情况就是不可重复读.幻读
: 事务A开始事务, 正在修改id为1-50的数据, 当修改到40行时候, 再次读取第一行数据, 发现第一行数据似乎没有被修改, 其实它是在被事务A修改后又被其他事务改回来了, 似乎产生了幻觉, 这就是幻读.
隔离级别
读未提交(read uncommitted)
事务B能够读取到事务A还没有提交的数据, 就是事务A未提交的中间数据能够被事务B读取到,读已提交
: 事务B只能够读取到事务A提交前或者提交后的数据, 不能读取到事务A未提交的中间数据.每次都会读取其他事务最新提交的快照.可重复读
: 事务B在还没有提交前, 对锁定的数据, 无论重复多少次读取, 都是一样的. 原因是在事务开始时候, 对对象采用了一致性读取在该事务开始时候的快照.可串行化
: 整张表, 一个时刻只能有一个事务在操作.
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交(read uncommitted) | ✔ | ✔ | ✔ |
读已提交(read committed) | ✘ | ✔ | ✔ |
可重复读(repeatable read) | ✘ | ✘ | ✔ |
可串行化(serializable) | ✘ | ✘ | ✘ |