# 隔离级
如果你对它不够了解,就有可能无意中在线上造成一些奇怪的数据问题,而且有可能这种 BUG 是偶发的,是无法被捕捉到的,间接造成了排查问题的成本过大。
而本篇文章就是告诉你会产生什么问题,在哪个阶段会产生问题以及如何避免。
# 什么是隔离级
ACID
代表事务的四种特征,其中 I
指的是 Isolate
,即隔离性。一个事务在最终提交之前对其它事务是不可见的,这就是隔离性。
但事实上,当并发过高时,多个事务的操作涉及到相同行的数据时,单个事务对其它事务并不一定完全不可见,此时可能看见事务提交前的中间状态,于是有了隔离级。
# 四种隔离级别
总共有四种隔离级别,隔离级越高,事务的不可见性更好,但随之带来的是数据库更高的开销。
# Read Uncommited (未提交读) 与 Dirty Read (脏读)
事务未提交前对其它事务也是可见的
首先说明,这是唯一可能产生脏读的隔离级,也是在生产环境中基本不会用的隔离级。
那什么是脏读呢?脏读可以读取到未提交的数据,这无论如何也是不能够忍受的。
以下是脏读的示例,A与B代表两个事务
事务A | 事务B |
---|---|
开启事务 | 开启事务 |
查询孙悟空的阳寿为300 | |
把孙悟空的阳寿改为无限大 | |
查询孙悟空的阳寿为无限大 (脏读) | |
提交事务 | 提交事务 |
# Read Commited (提交读) 与 Nonrepetable Read (不可重复读)
事务只能读取已提交的事务,它解决了脏读的问题
这是 postgres
的默认隔离级别,也是大部分后端项目所设置数据库的隔离级别,因此对于它所产生的问题要格外注意。
正因为它是提交读,当一个多次读操作的事务执行过程中夹杂了一个写操作的事务,此时可能出现不可重复读的问题。
不可重复度,即在同一事务中,两次读操作的结果不同。相对而言,这种情况出现的可能还比较苛刻。
事务A | 事务B |
---|---|
开启事务 | 开启事务 |
查询孙悟空的阳寿为300 | 查询孙悟空的阳寿为300 |
把孙悟空的阳寿改为无限大 | |
提交事务 | |
查询孙悟空的阳寿为无限大 (不可重复读) | |
提交事务 |
# Repetable Read (可重复读) 与 Phantom Read (幻读)
# 可能产生的 BUG
# 三种
# 实践
# 如何在数据库中查看当前的隔离级