MySQL 事务隔离级别

用户头像
长沙造纸农
关注
发布于: 2020 年 10 月 09 日


MySQL InnoDB所提供的事务满足ACID的要求,事务是通过事务日志中的redo log和undo log来实现原子性(undo log)、一致性(undo log)、持久性(redo log),事务通过锁机制实现隔离性。



1、事务隔离级别与实现

READ-UNCOMMITTED : "读未提交"

READ-COMMITTED : "读已提交" 或者 "读提交"

实现机制:修改时加排他锁,直到事务提交后才释放,读取时加共享锁,读取完释放。

REPEATABLE-READ : "可重复读" 或者 "可重读"。mysql默认使用级别

实现机制:读取数据时加共享锁,写数据时加排他锁,都是事务提交才释放锁。采用"一致性非锁定读"的机制提高了数据库并发性(非锁定读),使用 MVCC (多版本并发控制)实现。

SERIALIZABLE : "串行化"。

实现机制:所有的读操作均为当前读,读加读锁 (S锁),写加写锁 (X锁)。采用的是RangeS_S模式,锁定检索范围为只读,这样就避免了幻影读问题,表级锁

show processlist ;#查看连接线程
show variables like 'tx_isolation'; #查看隔离级别
mysql> set @@session.tx_isolation='READ-UNCOMMITTED'; #设置当前线程隔离级别,GLOBAL全局
Query OK, 0 rows affected, 1 warning (0.00 sec)

启动两个不同线程的客户端:

设置事务隔离级别并查看:

读未提交:





读已提交:





可重复读:



注意:

※ 可重复读仅在事务开始时创建一次快照,而读提交每次执行语句都会重新创建一次快照。



可重复读-幻读:



可重复读-并发写阻塞(索引列使用行锁):

可重复读-并发写阻塞(非索引列使用表锁):

可重复读-间隙锁:



Next-Key锁:

注意:

※ age为索引,当操作age=28时,不仅针对该记录加行锁,且两侧加间隙锁,33<=age不受影响;

    age不为索引时,对整表加间隙锁;

※ 并发写问题利用行锁解决,解决幻读用间隙锁,MySQL 把行锁和间隙锁合并「Next-Key锁」使用,解决并发写和幻读。



2、脏读、幻读、不可重复

脏读:当前事务可以查看到别的事务未提交的数据(侧重点在于别的事务未提交)。

幻读:幻读的侧重点在于新增和删除(数据量的变化)。表示在同一事务中,使用相同的查询语句,第二次查询时,莫名的多出了一些之前不存在数据,或者莫名的不见了一些数据(MySQL 的可重复读隔离级别通过间隙锁解决了幻读问题,但插入相同主键会冲突)。

不可重读:不可重读的侧重点在于更新修改数据(数据内容的更新)。同一事务中,查询相同的数据范围时,同一个数据资源莫名的改变了。



3、隔离界别区别

事务的隔离级别越高,隔离性越强,数据问题越少,并发能力越弱。


发布于: 2020 年 10 月 09 日 阅读数: 32
用户头像

长沙造纸农

关注

曾梦想仗剑走天涯,后来BUG太多没去! 2020.07.06 加入

还未添加个人简介

评论

发布
暂无评论
MySQL事务隔离级别