MySqL事务特性,隔离级别
MySqL事务隔离级别
事务的特性:
原子性:事务要么全部提交成功要么全部失败
一致性:事务操作前和操作后具有完整性约束,数据库保持一致性状态
隔离性:事务执行时相互隔离互不影响,可以防止多个事务并发执行由于交叉执行导致的不一致
持久性:事务操作结束后修改是永久性的,即使关机故障也不会消失
MySQL InnoDB 引擎通过什么技术来保证事务的这四个特性的呢?
- 持久性是通过 redo log (重做日志)来保证的;
- 原子性是通过 undo log(回滚日志) 来保证的;
- 隔离性是通过 MVCC(多版本并发控制) 或锁机制来保证的;
- 一致性则是通过持久性+原子性+隔离性来保证;
事务的隔离级别有哪些?
读未提交
最低的隔离级别, 会导致脏读、幻读或不可重复读。
读已提交
允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。这是大多数数据库(如 Oracle, SQL Server)的默认隔离级别。
可重复读
对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。并且,InnoDB 在此级别下通过 MVCC(多版本并发控制) 和 Next-Key Locks(间隙锁+行锁) 机制,在很大程度上解决了幻读问题。
RR隔离级别甚至连部分情况的可重复读也没解决:事务A先快照读查到数据a=10,事务B更新a=15并提交,事务A再当前读数据,读出来是a=15,两次前后读取不一样。
当前读一定读取“最新已提交版本(Latest Committed Version)”,而不是事务开始时的快照。
可串行化
最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。
事务执行可能出现的问题
脏读 :当一个事务读到另一个没有提交事务修改过的数据,此时就发生脏读了。通过读已提交可以避免
不可重复读 : 在一个事务内多次读取同一个数据,如果出现前后两次读到的数据不一样的情况,就意味着发生了「不可重复读」现象。
幻读 : 在一个事务内多次查询某个符合查询条件的「记录数量」,如果出现前后两次查询到的记录数量不一样的情况,就意味着发生了「幻读」现象。


RR 隔离级别下如果第一次是快照读、第二次是当前读,确实可能读到不同的值;但严格来说,这并不属于不可重复读,因为比较的是两种不同的读语义。不可重复读只讨论同一种读方式。
在 RC 隔离级别下,虽然普通快照读无法避免不可重复读,但如果显式使用当前读并加锁,同样可以通过锁机制避免前后读取不一致。



