- 读未提交 (read uncommitted): 隔离级别最低, 一个事务还未提交时, 它做的变更就能被别的事务看到.
- 读提交 (read committed): 一个事务提交后, 它做的变更才能被其它事务看到. 解决了脏读
- 怎么解决脏读的呢? 每次读都会生成一个ReadView, 会顺着MVCC版本链去读第一个已提交事务的历史记录
- 可重复读 (repeatable read): 一个事务执行过程中读取的数据, 总是和这个事务第一次读取的数据是一致的. 解决了不可重复读
- 怎么解决不可重复读的呢? 只有第一次读才会生成一个ReadView, 这样就算后续有事务提交也不会影响查询结果
- 如果第二次读之前执行过一条范围写命令, 而这个范围刚好包含了另一事务插入的新记录, 幻读仍然可能发生, 因为写命令是当前读, 可以在当前读的范围内加S锁来避免插入数据, 从而避免幻读
- 串行化 (serializable): 隔离级别最高, 使用普通的select语句会对访问过的记录加S锁, 这样就阻止了其它事务修改该记录, 解决了幻读
- 怎么解决幻读的呢? 读记录时会加S锁, 别的事务在此范围内的记录进行写操作都会阻塞, 直到该事务提交
无论是哪种隔离级别, 写同一行记录时都会加X锁, 所以都能解决脏写问题,
设置四种事务隔离级别是“舍弃 一部分隔离性 换取 更好的并发性能”, 所以严格地说, 只有串行化才满足绝对的隔离性