彻底搞懂Mysql Innodb事务隔离级别

460 阅读3分钟

        事务是程序执行过程中的一个执行单元,特点是该执行单元要么全部成功,要么全部失败。

        事务包含正常操作和失败补偿操作,而失败补偿操作就包含回滚,因此事务实现的大多数实现都是补偿实现。 mysql中采用补偿操作手段为回滚,即不成功就返回初始状态。一些第三方框架采用补偿,尽量多试几次失败操作,如果仍不成功,则回滚的方案。 

1、事务的四大特性 (ACID)

  • 原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。
  •  一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。 
  •  隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。
  •  持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。

2、并发事务的隔离级别

隔离级别	             脏读(Dirty Read)  不可重复读(NonRepeatable Read)	幻读(Phantom Read)
读未提交(Read uncommitted    可能	        可能	                        可能
读已提交(Read committed)    不可能	        可能	                        可能
可重复读(Repeatable read)   不可能	        不可能	                        可能
串行化(Serializable )       不可能	        不可能	                        不可能
  • 读未提交(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据 
  • 读已提交(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (存在不可重复读问题
  • 可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,(存在幻读) 
  • 串行化(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

注:

        1、不可重复读侧重于更新操作。例如:事务a反复读取一条数据,事务b在事务a读取过程中,修改了这条数据。结果导致事务a读取的这条数据发生了变化,导致前后读取的数据不止一致问题,即不可重复度问题。

        2、幻读侧重于增删操作。例如:事务a读取一个列表,长度为10;当事务a反复读取时,这个列表长度也应该为10;但是,事务b在期间,插入或删除了一条数据,导致事务a读取列表时前后长度不一致,数据幽灵般的增加或消失了,因此形成幻读。