谈隔离级别之前,我们要了解数据库中常见的三个问题
-
脏读:事务 A 可以访问到事务 B 尚未提交的更改
-
不可重复读:一个事务前后读取的同一条记录发生了改变或删除,针对的是 delete 和 update 操作
-
幻读:一个事务按照相同的查询条件查询出的结果集中较之前出现了新数据,针对的是 insert 操作
第一级别:读未提交 read uncommitted
- 最低的隔离级别,简单概括为没有提交就可以读到。即事务 A 可以读取到事务 B 还没有提交的更改
- 实现原理:直接读写,不做控制
- 存在的问题:脏读、不可重复读、幻读、更新丢失
- 这种隔离级别是理论上的,大多数的数据库都是第二级别起步
第二级别:读已提交 read committed
- 简单概括为只能读取到提交后的数据。即事务 A 可以读取到事务 B 已提交的更改
- 实现原理:MVCC
- 存在的问题:不可重复读、幻读、更新丢失
- 这种隔离级别是最真实的数据,也是 oracle 默认的隔离级别
第三级别:可重复读 repeatable read
- 简单概括为提交之后也读不到,即事务 A 不可以读取到事务 B 已提交的更改
- 实现原理:MVCC
- 存在的问题:幻读、更新丢失
- 是 mysql 的默认隔离级别
第四级别:序列化/串行化 serializable
- 效率最低,解决了所有的问题。这种级别表示事务间处理相关联的数据时需要进行排队,不能并发
- 中心思想就是事务 A 操作或读取到的数据在事务 B 中不可以更改,并且在 A 查询数据的间隙中不可以插入
- 每次读取的数据都是真实的,但效率很低。一般不使用
查看与设置事务隔离级别的 sql 语句
- 查看当前数据库事务隔离级别(就是查询 mysql 中记录事务隔离级别的系统变量)
select @@transaction_isolation; -- 结果为 REPEATABLE-READ ,mysql 默认的隔离级别
- 全局设置当前连接中的所有数据库的事务隔离级别(不是即时生效,需要重新连接数据库时才会生效)
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED
- 设置当前会话(客户端连接数据库到断开连接的过程)中数据库的隔离级别,即时生效
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED