MySQL 事务隔离级别
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模式,锁定检索范围为只读,这样就避免了幻影读问题,表级锁。
启动两个不同线程的客户端:
设置事务隔离级别并查看:
读未提交:
读已提交:
可重复读:
注意:
※ 可重复读仅在事务开始时创建一次快照,而读提交每次执行语句都会重新创建一次快照。
可重复读-幻读:
可重复读-并发写阻塞(索引列使用行锁):
可重复读-并发写阻塞(非索引列使用表锁):
可重复读-间隙锁:
Next-Key锁:
注意:
※ age为索引,当操作age=28时,不仅针对该记录加行锁,且两侧加间隙锁,33<=age不受影响;
age不为索引时,对整表加间隙锁;
※ 并发写问题利用行锁解决,解决幻读用间隙锁,MySQL 把行锁和间隙锁合并「Next-Key锁」使用,解决并发写和幻读。
2、脏读、幻读、不可重复
脏读:当前事务可以查看到别的事务未提交的数据(侧重点在于别的事务未提交)。
幻读:幻读的侧重点在于新增和删除(数据量的变化)。表示在同一事务中,使用相同的查询语句,第二次查询时,莫名的多出了一些之前不存在数据,或者莫名的不见了一些数据(MySQL 的可重复读隔离级别通过间隙锁解决了幻读问题,但插入相同主键会冲突)。
不可重读:不可重读的侧重点在于更新修改数据(数据内容的更新)。同一事务中,查询相同的数据范围时,同一个数据资源莫名的改变了。
3、隔离界别区别
事务的隔离级别越高,隔离性越强,数据问题越少,并发能力越弱。
版权声明: 本文为 InfoQ 作者【长沙造纸农】的原创文章。
原文链接:【http://xie.infoq.cn/article/ff6d0588de96a996238863fc2】。文章转载请联系作者。
评论