MST

星途 面试题库

面试题:PostgreSQL并发异常之脏读问题及解决

在PostgreSQL中,脏读是一种常见的并发异常现象,请描述脏读具体是什么,在什么场景下可能出现脏读,以及如何通过PostgreSQL的机制(如隔离级别等)来避免脏读?
14.0万 热度难度
数据库PostgreSQL

知识考点

AI 面试

面试题答案

一键面试

脏读定义

脏读指一个事务读取到了另一个事务未提交的数据。当一个事务对数据进行修改但尚未提交,此时另一个事务读取了这些未提交的修改数据,如果第一个事务回滚,那么第二个事务读取到的数据就是无效的“脏数据”。

可能出现脏读的场景

假设有两个事务 T1T2T1 开始对某条数据(例如账户余额)进行修改,将余额从1000元改为800元,但还未提交事务。这时 T2 读取该账户余额,得到的值是800元。如果之后 T1 因为某些原因回滚了事务,那么账户余额应该还是1000元,T2 读取到的800元就是脏数据。在银行转账、库存管理等涉及数据实时更新和读取的业务场景中容易出现这种情况。

通过PostgreSQL机制避免脏读

在PostgreSQL中,可以通过设置合适的隔离级别来避免脏读。PostgreSQL支持以下几种隔离级别:

  1. 读未提交(Read Uncommitted):此级别允许脏读,即一个事务可以读取到另一个未提交事务修改的数据,所以不能避免脏读。
  2. 读已提交(Read Committed):默认隔离级别,一个事务只能读取到已经提交的数据,可避免脏读。在这种隔离级别下,T2 只有在 T1 提交事务后才能读取到 T1 修改的数据,从而避免了读取到未提交的脏数据。
  3. 可重复读(Repeatable Read):不仅避免脏读,还保证在同一个事务内多次读取相同数据时,得到的数据是一致的,即使其他事务在此期间对数据进行了修改并提交。
  4. 串行化(Serializable):最严格的隔离级别,完全避免并发问题,通过强制事务串行执行来保证数据一致性,自然也能避免脏读。但此级别性能开销较大,因为会限制事务的并发执行。

通过将隔离级别设置为“读已提交”及以上级别(如“可重复读”“串行化”),就可以有效避免脏读现象在PostgreSQL中发生。