[SQL系列] 从头开始学PostgreSQL 借鉴MYSQL的隔离级别

SQL 的隔离级别是指在数据库中,事务之间相互隔离的程度。当事务 A 修改了某条数据后,如果事务 B 在这个时候读取该数据,会发生什么情况呢?这取决于数据库的隔离级别设置。
常用的事务隔离级别类型包括以下几种:

  1. READ UNCOMMITTED(读未提交):该隔离级别允许读取未提交的事务所做的修改,但未提交的事务不能读取已提交的事务所做的修改。因此,该隔离级别可能会导致脏读和不可重复读的问题。
  2. READ COMMITTED(读已提交):该隔离级别只允许读取已提交的事务所做的修改,而不能读取未提交的事务所做的修改。因此,该隔离级别可以避免脏读的问题,但是可能会导致不可重复读的问题。
  3. REPEATABLE READ(可重复读):该隔离级别允许读取已提交的事务所做的修改,并且同一个事务多次读取同一数据时,其结果保持一致。因此,该隔离级别可以避免不可重复读的问题,但是可能会导致幻读的问题。
  4. SERIALIZABLE(串行化):该隔离级别相当于所有事务都串行执行,可以避免所有的并发问题,但是会严重影响性能。

首先需要了解几个名词:

1. 脏读:在一个事务窗口中,没有数据修改提交前,另一个事务就可以看到内存中数据页的修改。也就是在事务窗口中可以读取到别人没有提交的数据信息。

比如事务A修改了一个数据,但是还没提交

事务B就读取到了这个修改的值

这时候事务A突然间roll back了

事务B就相当于读到了不存在的数据

2. 不可重复读:指的是在一个十五窗口内,最开始独到的数据和事务结束前的任意时刻读到的同一批数据出现不一致的情况。

比如事务A多次读取一个数据,

事务B在其中更新了数据并且提交了

事务A的多次读取结果不一样。

3. 幻读:当事务不是独立执行时,一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。例如,第一个事务读取了表中的所有行,然后第二个事务插入了一行新数据,这导致第一个事务读取的数据行不完整,产生了幻读的现象。

两次select获取到的数量不一样,比如说第一次 select拿到了10行,第二次select有20行。

比如说,事务A第一次select数据时,拿到了5行数据

事务B在此时插入了5行

第二次事务Aselect数据时就拿到了10行数据,要是原本准备从第6行开始insert,这时候就会冲突

隔离级别  脏读 不可重复读 幻读
读未提交 发生      发生 发生
读已提交 不发生 发生 发生
可重复读 不发生 不发生 在next-key lock解决
串行读 不发生 不发生 不发生

对于读未提交来说,在事务中修改了数据还没提交但是却会被其他事务所看到

脏读不可避免,不可重复读也是,幻读也是

对于读已提交来说,在事务中修改了数据提交了才会被其他事务看到

脏读完全可以避免,但是如果重复读时正好提交就不对了,所以无法避免不可重复读和幻读

对于可重复读来说,可以避免脏读和不可重复读

Read View是MySQL在可重复读隔离级别下创建的一个视图,它为每个事务提供了一个一致性的数据快照。Read View记录了在事务开始时活跃的所有事务ID。通过Read View,事务可以读取到其他事务修改前的数据行,从而实现可重复读,是为mvcc服务的。

对于串行化,会将所有的事务都串行执行,就可以避免所有的并发问题,但是效率就很低了。

你可能感兴趣的:(sql,sql,postgresql,数据库)